# API Reference Source: https://boxo.mintlify.app/MiniApp API Reference/APIReference ## Miniapp initialization ### `AppBoxoWebAppInit` An event to notify host app about miniapp's initialization ### `AppBoxoWebAppGetInitData` Gets init data from host app **Returns an object with:** * ` app_id` Miniapp ID * ` client_id` Host client ID * ` payload` String consisting of encrypted user details * ` data {[key: string]: any}` null custom data passed from Hostapp * ` token` *optional* User session token if it is still active **TIP** There is a shortcut `.getInitData()` that handles saving details above in cookies or localStorage and returns a Promise. ## Miniapp manipulation ### `AppBoxoWebAppOpenMiniApp` Opens other miniapp based on provided application ID **Parameters** * `app_id` *required* Miniapp ID to open ### `AppBoxoWebAppCloseMiniApp` Close current active miniapp ### `AppBoxoWebAppOnRestore` Event that is fired when miniapp is restored. Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type } = event.detail if (type === 'AppBoxoWebAppOnRestore') { // Miniapp restored } }) ``` ## Authentication ### `AppBoxoWebAppLogin` Login user using credentials given from host app Example: ```js theme={"system"} const login = async (data) => { const response = await appboxo.sendPromise('AppBoxoWebAppLogin', data) // Returns http response console.log(response) } ``` **TIP** There is a shortcut that you can use: ```js theme={"system"} appboxo.login(data).then(response => { console.log(response) }).catch(error => { console.log(error) }) ``` ### `AppBoxoWebAppLogout` Logout and clear session token Example: ```js theme={"system"} const logout = async (data) => { await appboxo.sendPromise('AppBoxoWebAppLogout') } ``` **TIP** There is a shortcut that you can use: ```js theme={"system"} appboxo.logout().then(() => { // logged out }).catch(error => { console.log(error) }) ``` ### `AppBoxoWebAppClearToken` Clears saved token in host app ### `AppBoxoWebAppSaveToken` Saves provided token in host app **Parameters** * `token` *required* Token to save in host app ## Appboxo Pay **WARNING** This event is available from version 1.3.13 and above ### `AppBoxoWebAppPay` Send payment event to host app orderPaymentId:string, amount: number, orderId: string, currency: string, extraParams?: any **Parameters** * `orderPaymentId` *required* `string` Order payment identifier * `miniappOrderId` *required* `number` Unique identifier for the current payment * `amount` *required* `boolean` Payment amount * `currency` *required* `string` Define currency code * `extraParams` : `any` Any extra data Example: ```js theme={"system"} appboxoSdk.send('AppBoxoWebAppPay', { orderPaymentId: "xxx", amount: 199.00, miniappOrderId: "TM121248847", currency: "USD", extraParams: {} }) ``` To receive the result of the payment event, just subscribe to the same event. Host app will sending these as the response: **Parameters** * `orderPaymentId` : `string` Order payment identifier * `miniappOrderId`: `number` Unique identifier for the current payment * `hostappOrderId` : `number` Unique identifier from hostapp * `amount` : `boolean` Payment amount * `currency` : `string` Define currency code * `status` : `string` Status of the payment * `extraParams` : `any` Any extra data Example: ```js theme={"system"} const appboxoPaymentStatusHandler = (event) => { if (!event.detail) { return; } const { type, data } = event.detail; if (type === 'AppBoxoWebAppPay') { setResponse(data.status) } } ``` ## Tab bar ### `AppBoxoWebAppSetTabBar` Initialized native tab bar component **Parameters** * `show` required `boolean` Defines TabBar visibility * `activeTab` required `number` Active TabBar item id * `list` required `Array<{ tabId: number, tabName: string, tabIcon: string }> Define tabs` * `options` required `{ color: string, background: string, selectedColor: string, hasBorder: boolean, borderColor: string }` Tab bar options * `badges` optional `Array<{ tabId: number, background: string, color: string, value?: string }>` Define tab item badges. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppSetTabBar', { show: true, activeTab: 1, list: [ { tabId: 1, tabName: 'Home', tabIcon: ICON_URL }, { tabId: 2, tabName: 'About', tabIcon: ICON_URL }, { tabId: 3, tabName: 'Services', tabIcon: ICON_URL } ], badges: [ { tabId: 1, background: '#ff0000', color: '#ffffff', value: '4' }, { tabId: 3, background: '#ff0000', color: '#ffffff', value: '1' } ], options: { color: '#aaaaaa', background: '#ffffff', selectedColor: '#2eb8da', hasBorder: true, borderColor: '#dddddd' } }) ``` Sending event with only required changes will preserve initial options: ```js theme={"system"} appboxo.send('AppBoxoWebAppSetTabBar', { activeTab: 2 }) ``` ```js theme={"system"} appboxo.send('AppBoxoWebAppSetTabBar', { options: { color: '#ffffff', background: '#000000', selectedColor: '#2eb8da', hasBorder: false } }) ``` ### `AppBoxoWebAppTabBarItemClick` Event that should be subscribed to in order to get active tab item click Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppTabBarItemClick') { if (data.tabId) { // Active tab id received } } }) ``` ## Navigation bar ### `AppBoxoWebAppSetNavigationBar` Activates native navigation bar. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppSetNavigationBar', { title: 'Light nav bar', // Navigation bar title backButton: true, // Controls back button visibility background: '#ffffff', // Navigation bar background color frontColor: '#000000', // Navigation bar and status bar accent color show: true // Controls navigation bar visibility, isBackgroundTransparent: true, // When set to true, will make background transparent frontColorWhenTransparent: '#ffffff', // Navigation bar and status bar accent color when navigation has transparent background changeBackgroundOnScroll: true // Will smoothly change backgroound from transparent to `background` color on scroll }) ``` Sending event with only required changes will preserve initial options: ```js theme={"system"} appboxo.send('AppBoxoWebAppSetNavigationBar', { title: 'Changed some time later' }) ``` ## Action buttons ### `AppBoxoWebAppSetActionButton` Changes actions button theme. By default it is dark. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppSetActionButton', { isLight: true }) ``` ## Loading indicator ### `AppBoxoWebAppLoadingIndicator` Show native loading indicator. **Important:** Loading indicator will timeout after 30 seconds with prompt to hide it if no event is dispatched to change it. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppLoadingIndicator', { show: true }) ``` ## QR code reader ### `AppBoxoWebAppOpenQRCodeReader` Opens native QR code reader. *This method will prompt a permission request for camera.* Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppOpenQRCodeReader'); ``` Results from QR code reader are received by events: `AppBoxoWebAppOpenQRCodeReaderResult` or `AppBoxoWebAppOpenQRCodeReaderFailed` Example: ```js theme={"system"} // Subscribe to events to receive data appboxo.subscribe(event => { if (!event.detail) { return; } const { type, data } = event.detail; if (type === 'AppBoxoWebAppOpenQRCodeReaderResult') { // Reading result of the QR Code Reader console.log(data.code_data); } if (type === 'AppBoxoWebAppOpenQRCodeReaderFailed') { // Catching the error console.log(data.error_type, data.error_data); } }); ``` ## Haptic feedback ### `AppBoxoWebAppVibrate` Triggers haptic engine on the device, if available. **Parameters** * `style` optional `'light' | 'medium' | 'heavy'` Controls strength of vibration, defaults to 'light'. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppVibrate', { style: 'medium' }) ``` ## Action sheet ### `AppBoxoWebAppShowActionSheet` Shows native action sheet **Parameters** `header` *optional* `string` Action sheet header text `list` *required* `Array<{ id: number, text: string, role?: 'cancel' | 'destructive' | 'selected' }>` Define action sheet items Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppShowActionSheet', { header: 'Albums', list: [ { id: 1, text: 'Delete', role:'destructive' }, { id: 2, text: 'Selected', role:'selected' }, { id: 3, text: 'Share', }, { id: 4, text: 'Play', }, { id: 5, text: 'Cancel', role: 'cancel' } ] }) ``` ### `AppBoxoWebAppActionSheetItemClick` Event that should be subscribed to in order to get action sheet item click Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppActionSheetItemClick') { if (data.id) { // Action sheet item id received } } }) ``` ## Geolocation ### `AppBoxoWebAppGetGeodata` Requests user geodata. *This method will prompt a permission request to access geolocation.* Example: ```js theme={"system"} const getGeodata = async () => { const data = await appboxo.sendPromise('AppBoxoWebAppGetGeodata'); return { isAvailable: !!data.available, lat: parseFloat(data.lat), long: parseFloat(data.long) }; }; ``` ## Map ### `AppBoxoWebAppChooseLocation` Open full screen map to choose location *This method will prompt a permission request to access geolocation.* Example: ```js theme={"system"} const chooseLocation = async () => { const data = await appboxo.sendPromise('AppBoxoWebAppChooseLocation'); return { latitude: parseFloat(data.latitude), longitude: parseFloat(data.longitude) }; }; ``` ### `AppBoxoWebAppOpenLocation` Open full screen map to that shows markered location *This method will prompt a permission request to access geolocation.* Example: ```js theme={"system"} const openLocation = async () => { const data = await appboxo.sendPromise('AppBoxoWebAppOpenLocation', { latitude: 42.5264986, longitude: 74.5788997, scale: 13 }); console.log(data) // Returns: // { // result: true // } }; ``` ## Alert ### `AppBoxoWebAppShowAlert` Show native alert box **Parameters** `header` *optional* `string` Alert header text `message` *optional* `string` Alert message `buttons` *required* ` Array<{ id: number, text: string, role?: 'cancel' | 'destructive' }>` Define buttons Example: ```js theme={"system"} const showAlert = async () => { const data = await appboxo.sendPromise('AppBoxoWebAppShowAlert', { header: 'Native alert', message: 'This is a native alert box.', buttons: [ { id: 1, text: 'Cancel', role:'destructive' }, { id: 2, text: 'Ok' } ] }); // Selected button const selectedButton = data.id }; ``` ## Image gallery ### `AppBoxoWebAppShowImages` Open full screen native image gallery **Parameters** `start_index` *optional* `number` Index to start showing from `images` *required* `Array` Image urls Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppShowImages', { images: [ // image urls ] }); ``` After image gallery is closed, same event will be dispatched back to miniapp with result data. Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppShowImages') { if (data.result) { // Image gallery has been shown successfully } else { // There were problems loading provided images } } }) ``` ## Storage ### `AppBoxoWebAppStorageGet` Requests a value from the storage **Parameters** `keys` *required* `Array` Keys for getting (\[a-zA-Z\_-0-9]) Example: ```js theme={"system"} const getUserData = async () => { const userData = await appboxo.sendPromise('AppBoxoWebAppStorageGet', { keys: ['username', 'email'] }); console.log(userData) // Returns: // { // keys: [ // { // key: 'username', // value: 'John' // }, // { // key: 'email', // value: 'john@doe.com' // } // ] // } }; ``` ### `AppBoxoWebAppStorageGetKeys` Request list of keys of some stored values **Parameters** `count` *required* `number` Count of keys to get. Max value is 1000 `offset` *optional* `number` The offset required to fetch a specific subset of keys. Default: 0 Example: ```js theme={"system"} const getStorageKeys = async () => { const storageKeys = await appboxo.sendPromise('AppBoxoWebAppStorageGetKeys', { count: 10 }); console.log(storageKeys); // Returns: // { // keys: ['username', 'email'] // } }; ``` ### `AppBoxoWebAppStorageSet` Stores value in storage Parameters `key` *required* `string` The key of value (\[a-zA-Z\_-0-9]) `value` *optional* `string` value Example: ```js theme={"system"} const saveData = async ({ key, value }) => { const response = await appboxo.sendPromise('AppBoxoWebAppStorageSet', { key, value }); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppStorageRemove` Removes value in storage **Parameters** `key` *required* `string` The key of value (\[a-zA-Z\_-0-9]) Example: ```js theme={"system"} const removeData = async ({ key }) => { const response = await appboxo.sendPromise('AppBoxoWebAppStorageRemove', { key }); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppStorageClear` Clears all data in storage Example: ```js theme={"system"} const clearStorage = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStorageClear'); console.log(response); // Returns: // { // result: true // } }; ``` ## Clipboard ### `AppBoxoWebAppGetClipboard` Gets the content on the system clipboard. Example: ```js theme={"system"} const getClipboard = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppGetClipboard'); console.log(response); // Returns: // { // data: 'from clipboard or null' // } }; ``` ### `AppBoxoWebAppSetClipboard` Sets the content on the system clipboard. Parameters `data` *required* `string` Content to be copied to clipboard Example: ```js theme={"system"} const setClipboard = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppSetClipboard', { data: 'copied to clipboard' }); console.log(response); // Returns: // { // result: true // } }; ``` ## System information ### `AppBoxoWebAppGetSystemInfo` Gets system information. Example: ```js theme={"system"} const getSystemInfo = async () => { const systemInfo = await appboxo.sendPromise('AppBoxoWebAppGetSystemInfo'); console.log(systemInfo); // Returns: // { // brand: 'Apple Inc.', // model: 'iPhone 7 Plus', // pixelRatio: 3, // screenWidth: 414, // screenHeight: 736, // windowWidth: 414, // windowHeight: 672, // statusBarHeight: 20, // system: 'iOS 10.0.1', // platform: 'iOS / iPhone OS', // SDKVersion: 1.0.4, // cameraAuthorized: true, // locationAuthorized: false, // locationEnabled: false, // } }; ``` ## Accelerometer ### `AppBoxoWebAppStartAccelerometer` Starts listening on acceleration data. Example: ```js theme={"system"} const startAccelerometer = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStartAccelerometer', { interval: 200 // Update interval in ms }); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppStopAccelerometer` Stops listening on acceleration data. Example: ```js theme={"system"} const stopAccelerometer = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStopAccelerometer'); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppOnAccelerometerChange` Listens on the acceleration data event. You can send AppBoxoWebAppStopAccelerometer event to stop listening. Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppOnAccelerometerChange') { console.log(data.x) console.log(data.y) console.log(data.z) } }) ``` ## Gyroscope ### `AppBoxoWebAppStartGyroscope` Starts listening on gyroscope data. Example: ```js theme={"system"} const startAccelerometer = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStartGyroscope', { interval: 200 // Update interval in ms }) console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppStopGyroscope` Stops listening on gyroscope data. Example: ```js theme={"system"} const stopAccelerometer = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStopGyroscope'); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppOnGyroscopeChange` Listens on the gyroscope data event. You can send AppBoxoWebAppStopGyroscope event to stop listening. Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppOnGyroscopeChange') { console.log(data.x) console.log(data.y) console.log(data.z) } }) ``` ## Compass ### `AppBoxoWebAppStartCompass` Starts listening on compass data. Example: ```js theme={"system"} const startCompass = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStartCompass') console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppStopCompass` Stops listening on compass data. Example: ```js theme={"system"} const stopCompass = async () => { const response = await appboxo.sendPromise('AppBoxoWebAppStopCompass'); console.log(response); // Returns: // { // result: true // } }; ``` ### `AppBoxoWebAppOnCompassChange` Listens on the compass data event. You can send AppBoxoWebAppStopCompass event to stop listening. Example: ```js theme={"system"} appboxo.subscribe((event) => { if (!event.detail) { return } const { type, data } = event.detail if (type === 'AppBoxoWebAppOnCompassChange') { console.log(data.direction) } }) ``` ## Background color ### `AppBoxoWebAppSetBackgroundColor` Dynamically sets the background color of the window. ```js theme={"system"} appboxo.send('AppBoxoWebAppSetBackgroundColor', { color: '#ff0000' }); ``` ## Status bar color ### `AppBoxoWebAppSetStatusBarColor` Dynamically sets the status bar color ```js theme={"system"} appboxo.send('AppBoxoWebAppSetStatusBarColor', { color: '#ffffff' }) ``` ## Tracking ### `AppBoxoWebAppTrack` Send postback tracking data about transaction Example: ```js theme={"system"} const sendTransactionData = async (data) => { const response = await appboxo.sendPromise('AppBoxoWebAppTrack', data) // Returns http response console.log(response) } sendTransactionData({ action: 'transaction', payload: { shipping: 5, tax: 0.57, discount: 2.25, currency_code: 'USD', customer: { // Optional first_name: 'John', last_name: 'Doe', email: 'jdoe@domain.com', ip_address: '234.192.4.75' }, items: [ { name: 'Product name', description: 'Product description', price: 8.80, amount: 2, total: 17.6, package_id: 1232 } ] } }) ``` **TIP** There is a shortcut that you can use to send tracking data: ```js theme={"system"} appboxo.track(data).then(response => { console.log(response) }).catch(error => { console.log(error) }) ``` ## Custom events ### `AppBoxoWebAppCustomEvent` Send custom event to host app. Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppCustomEvent', { type: 'any_string_identifier', // Any string identifier to be handled by host app payload: { // Any payload data to be send to host app // Your data } }) ``` ## Download file ### `AppBoxoWebAppDownloadFile` Send event to download file Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppDownloadFile', { url: 'url', file_name: 'filename.png' }) ``` ## Share text and file ### `AppBoxoWebAppShare` Send event to open native share modal Example: ```js theme={"system"} appboxo.send('AppBoxoWebAppShare', { text: 'text', url: 'url', file_name: 'filename.png' }) ``` # Authentication API Reference Source: https://boxo.mintlify.app/MiniApp API Reference/AuthenticationAPIRef ### `appboxo.login(optionalProps)` Sends a message to native client to open confirm modal with default confirmation message. Upon confirmation it sends request to platform and returns resolved authentication token promise to miniapp. **Parameters** * `optionalProps` *optional* Props to extend default login behavior **optionalProps** * `postConfirmCallback` *optional* Callback that is being called after confirm modal resolves **Example** ```js theme={"system"} try { const { // token string token } = await appboxo.login({ postConfirmCallback: (isConfirmed) => { console.log('Confirmation status: ', isConfirmed) } }); } catch (error) { // Handling an error } ``` ### `appboxo.logout()` Sends a message to native client to clear authentication tokens. # Events API Reference Source: https://boxo.mintlify.app/MiniApp API Reference/EventsAPI ## `.sendPromise(method[, params])` Sends a message to native client and returns the `Promise` object with response data **Parameters** `method` *required* The Boxo JS SDK method `params` *optional* Message data object **Example** ```js theme={"system"} // Sending event to client appboxo .sendPromise('AppBoxoWebAppGetInitData') .then(data => { // Handling received data console.log(data.email); }) .catch(error => { // Handling an error }); ``` You can also use imperative way ```js theme={"system"} try { const data = await appboxo.sendPromise('AppBoxoWebAppGetInitData'); // Handling received data console.log(data.email); } catch (error) { // Handling an error } ``` ## `.send(method[, params])` Sends a message to native client **Parameters** * `method` *required* The Boxo JS SDK method * `params` *optional* Message data object **Example** ```js theme={"system"} // App initialization appboxo.send('AppBoxoWebAppInit'); // Opening images appboxo.send('AppBoxoWebAppShowImages', { images: [ "https://pp.userapi.com/c639229/v639229113/31b31/KLVUrSZwAM4.jpg", "https://pp.userapi.com/c639229/v639229113/31b94/mWQwkgDjav0.jpg", "https://pp.userapi.com/c639229/v639229113/31b3a/Lw2it6bdISc.jpg" ] }) ``` ## `.subscribe(fn)` Subscribes a function to events listening **Parameters** `fn` *required* Function to be subscribed to events **Example** ```js theme={"system"} // Subscribing to receiving events appboxo.subscribe(event => { if (!event.detail) { return; } const { type, data } = event.detail; if (type === 'AppBoxoWebAppOpenQRCodeReaderResult') { // Reading result of the Code Reader console.log(data.code_data); } if (type === 'AppBoxoWebAppOpenQRCodeReaderFailed') { // Catching the error console.log(data.error_type, data.error_data); } }); // Sending method appboxo.send('AppBoxoWebAppOpenQRCodeReader', {}); ``` ## `.unsubscribe(fn)` Unsubscribes a function from events listening **Parameters** * \`\`\`fn\`\` *required* Event subscribed function **Example** ```js theme={"system"} const fn = event => { // ... }; // Subscribing appboxo.subscribe(fn); // Unsubscribing appboxo.unsubscribe(fn); ``` ## `.supports(method)` Checks if an event is available on the current device **Parameters** * `method` *required* The Boxo JS SDK method ## `.isWebView()` Returns `true` if Boxo JS SDK is running in mobile app, or `false` if not # Android Source: https://boxo.mintlify.app/changelog/android ## \[1.45.1] - 2026-07-29 * bump play-services-location to 21.3.0 and play-services-maps to 19.0.0 ## \[1.45.0] - 2026-07-22 * scope miniapp theme (dark/light) to the miniapp without changing the host app theme ## \[1.44.0] - 2026-07-21 * fix crash when host app removes NFC or VIBRATE permission from merged manifest * fix registerForActivityResult crash in QR scanner and map fragments ## \[1.43.1] - 2026-07-13 * fix window insets handling ## \[1.43.0] - 2026-06-12 * pass miniapp requiredFields to AuthListener.onAuth ## \[1.42.2] - 2026-06-04 * fix: saveState default logic ## \[1.42.1] - 2026-06-03 * add orderPaymentId field to PaymentData * add lottie animation as a miniapp loader ## \[1.40.5] - 2026-05-07 * Add user interaction tracking * enable background dimming for miniapps. ## \[1.40.4] - 2026-04-23 * fix background colors ## \[1.40.3] - 2026-04-20 * open miniapp as a dialog * remove multitask mode ## \[1.39.1] - 2026-03-05 * fix getGeolocation result when FusedLocationProvider fails ## \[1.39.0] - 2026-02-26 * add support for dark and light splash screen colors ## \[1.38.0] - 2026-02-17 * make auth and location prompts configurable from miniapps ## \[1.37.1] - 2026-02-17 * fix crash on location request ## \[1.37.0] - 2026-01-30 * update session events * add config for splash screen color * fix status bar and logo position ## \[1.36.1] - 2026-01-26 * fix proguard rules ## \[1.36.0] - 2026-01-20 * update location permission pop-up * support play-services-location and play-services-maps from version 17.0.0 ## \[1.35.0] - 2025-11-26 * update default value for saveState * add style\_5 for ActionButtons ## \[1.34.0] - 2025-11-18 * add esim direct install method ## \[1.33.2] - 2025-11-17 * add consent screen config ## \[1.33.1] - 2025-10-15 * rename clearLocalStorageKeysOnClose to noCacheLocalStorageKeys ## \[1.33.0] - 2025-10-15 * add config to clear localStorage keys on miniapp close ## \[1.32.2] - 2025-09-30 * add Accept-Language header to http requests ## \[1.32.1] - 2025-09-12 * merge AppBoxoAppShareBase64 with AppBoxoAppShare ## \[1.32.0] - 2025-09-11 * add share base64 file method ## \[1.31.0] - 2025-09-03 * add loading progress bar configs ## \[1.30.6] - 2025-08-27 * remove test dependencies ## \[1.30.5] - 2025-08-26 * fix auth bug * fix statusbar and navigation bar ## \[1.30.4] - 2025-08-20 * fix crashes when changing the system theme ## \[1.30.3] - 2025-08-19 * fix status bar icons color for dark mode ## \[1.30.2] - 2025-08-13 * some fixes ## \[1.30.0] - 2025-08-07 * add setAuthTokens method ## \[1.29.0] - 2025-07-30 * support dark mode logo ## \[1.28.0] - 2025-07-18 * enable resizeable activity ## \[1.26.0] - 2025-06-02 * target SDK downgraded to 34 to resolve compatibility issues ## \[1.25.0] - 2025-05-27 * updated android target sdk to 35 * removed android.support dependencies; Jetifier is no longer required. ## \[1.24.0] - 2025-05-21 * fix custom action button for style * add RESOURCE\_PROTECTED\_MEDIA\_ID permission to WebView ## \[1.23.0] - 2025-04-10 * rename Appboxo to Boxo * improve whitelisted url validation ( 'www' subdomain check) ## \[1.22.0] - 2025-04-09 * add new style for actionButtons (style\_4) * improve launch animations * fix sensor events ## \[1.21.0] - 2025-04-03 * add launch UI animations * change loader animation * improve session analytics * show error message with code only for sandbox ## \[1.20.1] - 2025-03-25 * proguard rules ## \[1.20.0] - 2025-03-24 * add page animation to miniapp config ## \[1.19.0] - 2025-03-12 * add events for native pullToRefresh ## \[1.18.0] - 2025-03-10 * add close button to error page * update some ui elements ## \[1.17.0] - 2025-02-26 * add camera to file picker if mime type is image/\* * fix AppBoxoWebAppStorageGet result * update text on qr scanner ## \[1.16.2] - 2025-02-19 * fix status and navigation bars ## \[1.16.1] - 2025-02-18 * fix screen size with bottom navigation bar ## \[1.16.0] - 2025-02-17 * Screen move up with keyboard * Consent screen for landscape mode * fix open location ## \[1.15.0] - 2025-02-13 * Add list of user fields to consent screen ## \[1.14.0] - 2025-01-07 * Fix problem with cookies and storage on logout ## \[1.13.0] - 2024-12-16 * LTR/RTL support by language ## \[1.12.1] - 2024-11-21 * fix open\_miniapp\_duration on reload ## \[1.12.0] - 2024-11-18 * new action button style (style\_3) ## \[1.11.2] - 2024-11-05 * change action buttons color for dark theme ## \[1.11.1] - 2024-11-01 * fix crash on loading dialog * show internet error only for main frame ## \[1.11.0] - 2024-10-25 * no internet connection page * open\_miniapp\_duration to GetInitData ## \[1.10.0] - 2024-10-21 * add maintenance mode ## \[1.9.0] - 2024-10-18 * add support eSim flag to AppBoxoWebAppGetSystemInfo ## \[1.8.3] - 2024-10-18 * reload after clear cache ## \[1.8.2] - 2024-10-16 * change miniapp settings expiration time to 60sec by default ## \[1.8.1] - 2024-10-11 * add progressbar to share file * more button icon for style\_2 ## \[1.8.0] - 2024-10-10 * add config fields to OpenMiniapp from miniapp * add new menu style (style\_2) ## \[1.7.0] - 2024-09-27 * add new menu style ## \[1.6.0] - 2024-09-25 * add showAboutPage flag to config * add visible option to AppBoxoWebAppSetActionButton event * fix open miniapp after closing miniapp ## \[1.5.21] - 2024-09-24 * system device hardware string ## \[1.5.20] - 2024-09-23 * remove http client cache ## \[1.5.19] - 2024-09-20 * AppBoxoWebAppShare to share file ## \[1.5.18] - 2024-09-13 * saveState flag to miniapp config ## \[1.5.17] - 2024-09-04 * Fix custom and payment event payload object's serialization ## \[1.5.16] - 2024-08-23 * Don't clear cache and localStorage on "Reload" ## \[1.5.15] - 2024-08-22 * AppBoxoWebAppDownloadFile to download file ## \[1.5.14] - 2024-08-22 * AppBoxoWebAppSetStatusBarColor to change status bar color ## \[1.5.13] - 2024-08-21 * clear cache and tokens when disabling User Data Sharing ## \[1.5.12] - 2024-08-20 * add language field to config to pass to miniapp * add file download implementation * save state when user close the miniapp ## \[1.5.11] - 2024-08-18 * set default empty video poster ## \[1.5.10] - 2024-08-15 * remove jcenter dependencies ## \[1.5.9] - 2024-08-12 * Sandbox mode ## \[1.5.8] - 2024-08-12 * Network timeouts ## \[1.5.7] * close miniapp page on multitask mode ## \[1.5.6] * consent t\&c, privacy text * consent button color from hostapp colors ## \[1.5.4] * updated Sentry endpoint ## \[1.5.3] * add listeners to minapp opened from miniapp ## \[1.5.2] * system info phone model to hardware codename ## \[1.5.1] * enableSplash flag to miniapp configs * fix close miniapp logic ## \[1.5.0] * Consent Management * Increase miniapp menu button size * Changed icons ## \[1.4.14] * fullscreen auth page * url\_suffix * default design for bottomsheet dialogs ## \[1.4.13] - 2021-12-09 * clear cache on reload * disable forceDarkAllowed ## \[1.4.12] - 2021-11-15 * hide clear cache functionality ## \[1.4.11] - 2021-11-10 * appboxo logo ## \[1.4.10] - 2021-09-21 * remove the word "miniapp" from menu items * clear cookies on clearCache ## \[1.4.9] - 2021-09-14 * onUserInteraction method to MiniappLifecycle * clear localStorage on clearCache ## \[1.4.8] - 2021-08-26 * onActivityResult invoking from AppboxoActivity ## \[1.4.7] - 2021-08-06 * permissionsPage flag to config * settings page moved to core ## \[1.4.6] - 2021-07-30 * isShopboxo flag moved to MiniappInfo * crash on login ## \[1.4.5] - 2021-07-27 * onGeolocationPermissionsShowPrompt implementation ## \[1.4.4] - 2021-07-19 * Pull miniapp settings for active miniapp from platform every 30seconds and invalidate cache if it has changed ## \[1.4.3] - 2021-06-30 * custom url loading handler * isShopboxo flag ## \[1.4.2] - 2021-06-18 * moves Payment to core module * renamed BaseMiniapp to Miniapp ## \[1.4.1] - 2021-06-15 * added debug mode flag to Config for debugging webview * added new auth flow * added sandbox mode * saving view states on changing screen orientation ## \[1.4.0] - 2021-05-26 * separated to light and full SDKs * injecting script into miniapp that will come from platform * support for android api 16 * proguard rules. --keepnames for all classes * auto screen orientaion in LightSDK ## \[1.3.46] - 2021-05-13 * bug with similar miniapps in list ## \[1.3.45] - 2021-05-07 * hide 'install app' banner for Agoda ## \[1.3.44] - 2021-05-07 * support for android api 19 ## \[1.3.43] - 2021-05-05 * "category" field to MiniappData ## \[1.3.42] - 2021-04-27 * getMiniapps() method (get approved miniapps) ## \[1.3.41] - 2021-04-21 * sets windowSoftInputMode "adjustResize" ## \[1.3.40] - 2021-04-12 * core version ## \[1.3.39] - 2021-03-16 * support multipleWindows mode for auth with socials * switcher for appboxo branding, disable whitelisting url flags ## \[1.3.38] - 2021-03-02 * hash sum to analytics tracking request data * disabled "about:blank" * get browser\_fallback\_url from uri with scheme intent:// ## \[1.3.37] - 2021-02-11 * removed params from getMiniapp method * added new methods to Miniapp to setting auth payload, additional user data, custom data ## \[1.3.36] - 2021-01-29 * use "browser\_fallback\_url" from intent ## \[1.3.35] - 2021-01-27 * add extra url params on first launch ## \[1.3.34] - 2021-01-25 * json response with JSONObject * crash on an incorrect app\_id with '/' symbol ## \[1.3.33] - 2020-12-23 * new method removeAllListeners() * remove all listeners on close miniapp * passing all listeners when miniapp opens another miniapp ## \[1.3.32] - 2020-12-07 * url change listener * option to add third action menu * extra query parameters to miniapp URL ## \[1.3.31] - 2020-11-17 * payment method ## \[1.3.30] - 2020-09-28 * http error handler * fixed launch analytics ## \[1.3.29] - 2020-09-15 * closing all miniapps on logout * renamed getMiniApp() to getMiniapp(), class MiniApp to Miniapp * dark/light support ## \[1.3.28] - 2020-09-09 * changed text inside auth permission dialog ## \[1.3.27] - 2020-09-08 * single/multi-window support ## \[1.3.26] - 2020-09-04 * fixed initial action buttons theme * fixed bug on click action buttons ## \[1.3.25] - 2020-08-26 * fixed clear cache ## \[1.3.24] - 2020-08-26 * fixed action buttons position * fixed action buttons theme ## \[1.3.23] - 2020-08-26 * fixed reload miniapp ## \[1.3.22] - 2020-08-25 * floating action buttons ## \[1.3.21] - 2020-08-24 * removed internal modifier from MiniApp 'appId' * miniapp error layout * crash on load miniappsettings * webView sound lags when app going background * removed platform token from miniapp data ## \[1.3.20] - 2020-08-21 * additional user fields for auth in miniapps * data field in miniapp from string to map * don't show the login dialog again if it is already opened ## \[1.3.19] - 2020-08-07 * action button's style from miniapp settings ## \[1.3.18] - 2020-07-30 * miniapp lifecycle listener ## \[1.3.17] - 2020-07-24 * moved login action from jssdk * moved transaction tracking from jssdk ## \[1.3.16] - 2020-07-07 * systemUiMode(light, dark) to system info * language to system info * error message when there is no integration * Appboxo.hideAllMiniApps() method to minimizing all miniapp screens ## \[1.3.15] - 2020-07-01 * AppboxoActivity.doOnActivityResult(...) method ## \[1.3.14] - 2020-06-24 * miniapp settings caching * pass "white\_label" field to miniapp settings * file chooser support * new methods Appboxo.getMiniApp(...) with params (authPayload - for auth, data - optional custom data to open miniapp). * fixed bug on reload & clear cache * Appboxo.createMiniApp(appId, payload) ## \[1.3.11] - 2020-06-11 * custom url schemes handler * miniapp close animation * fixed webview error handler * fixed miniappSettings ## \[1.3.10] - 2020-05-29 * MiniApp config class with colors * fade in to top effect when miniapps are switched * onRestore method * required fields from miniapp settings ## \[1.3.9] - 2020-05-22 * Miniapp settings * Compass * Instant miniapp reopening * Background color of the window * AppBoxoWebAppShowImages result callback return type * Render NavBar only when miniapp is loaded ## \[1.3.7] - 2020-05-15 * Bottom context menu * Status bar based on values from miniapp settings * Accelerometer * Gyroscope ## \[1.3.5] - 2020-05-08 * Landscape mode * Open location * Choose location * Haptic Feedback duration * NavigationBar title padding without icon # Capacitor JS Source: https://boxo.mintlify.app/changelog/capacitor ## \[0.15.0] * bump native sdk versions (android 1.45.1, ios 1.29.0) ## \[0.14.0] * add orderPaymentId field to Payment ## \[0.13.1] * add lottie animation support for miniapp splash loading indicator ## \[0.12.0] * remove multitask mode ## \[0.11.0] * add splash screen configuration options * fix sandbox mode ## \[0.10.0] * saveState is false by default * add style\_5 for ActionButtons * \[android] add esim direct install * update native sdk versions ## \[0.9.1] * fix ios build ## \[0.9.0] * add setAuthTokens method * update native sdk versions ## \[0.8.5] * fix bug on auth \[android] ## \[0.8.4] * fix crashes when changing the system theme ## \[0.8.3] * fix ui elements in dark mode ## \[0.8.2] * support dark mode logo ## \[0.8.1] * upgraded to target api 35 \[android] ## \[0.8.0] * upgrade to Cap7 ## \[0.7.1] * add miniapp page animation ## \[0.7.0] * add new menu style * improved whitelisted url behavior ## \[0.6.0] * add native pull to refresh * add camera option to file picker * other UI improvements ## \[0.5.0] * Added list of user fields to consent screen * Some improvements in native sdk ## \[0.4.0] 2025-01-23 * LTR/RTL support by language * Fix problem with cookies and storage on logout * Multiline error popup ## \[0.3.3] 2024-11-28 * add new menu style * fix open\_miniapp\_duration on reload ## \[0.3.2] 2024-11-5 * \[android] change action button color for dark theme ## \[0.3.1] 2024-11-1 * no internet connection page * fix crash on auth ## \[0.3.0] 2024-10-22 * clear cache with reload * add support eSim flag (android) * add maintenance mode ## \[0.2.8] 2024-10-16 * add miniapp settings expiration time to configs ## \[0.2.7] 2024-10-11 * changed more icon for style\_2 * added progressbar for share event ## \[0.2.6] 2024-10-10 * add new menu style (style\_2) ## \[0.2.5] 2024-10-01 * add new menu style (style\_1) ## \[0.2.4] 2024-09-26 * update native sdk dependencies * add aboutPage flag to show/hide "About Page" on miniapp menu ## \[0.2.3] 2024-09-24 * update native sdk dependencies ## \[0.2.1] 2024-09-20 * add native share modal ## \[0.2.0] 2024-09-18 * upgrade to Cap6 ## \[0.1.8] - cap5 2024-10-16 * add new menu style (style\_2) ## \[0.1.7] - cap5 * add new menu style (style\_1) ## \[0.1.6] - cap5 * add aboutPage flag to config * update native sdk dependencies ## \[0.1.5] - cap5 * add native share modal ## \[0.1.4] - 2024-09-13 * add saveState flag to openMiniapp ## \[0.1.3] - 2024-08-22 * add language field to config to pass to miniapp * add file download implementation * save state when user close the miniapp * clear cache and tokens when disabling User Data Sharing * add event to change status bar color ## \[0.1.2] - 2024-08-19 * set empty video poster as default \[android] ## \[0.1.1] 2024-08-12 * Add sandbox mode * Update network timeouts \[android] ## \[0.1.0] 2024-08-12 * Close miniapp if webview can't go back on press back button ## \[ios] * Fix play video inline \[ios] * Fix hide/show miniapp \[ios] ## \[0.0.5] 2024-08-12 * Revert renaming package for \[ios] ## \[0.0.4] 2024-08-12 * Add event listener type * Downgrade capacitor version and rename package # Expo Source: https://boxo.mintlify.app/changelog/expo ## \[0.15.0] * bump native sdk versions (android 1.45.1, ios 1.29.0) ## \[0.14.0] * add orderPaymentId field to Payment ## \[0.13.1] * add lottie animation support for miniapp splash loading indicator ## \[0.12.0] * remove multitask mode ## \[0.11.0] * add splash screen configuration options ## \[0.10.0] * saveState is false by default * add style\_5 for ActionButtons * android: esim direct install ## \[0.9.2] * android: add Consent screen config ## \[0.9.1] * ios: fix Consent screen ## \[0.9.0] * ios: add Consent screen config ## \[0.8.0] * add setAuthTokens method * bump native sdk versions ## \[0.7.0] * bump native sdk versions ## \[0.6.3] * add app.plugin.js ## \[0.6.2] * Some improvements in native sdk ## \[0.6.1] * add miniapp page animation ## \[0.6.0] * add new menu style * Added list of user fields to consent screen * add native pull to refresh * add camera option to file picker * other improvements in native sdk ## \[0.5.0] * Added list of user fields to consent screen * LTR/RTL support by language * Some improvements in native sdk ## \[0.4.2] * add new menu style * fix open\_miniapp\_duration on reload ## \[0.4.1] * no internet connection page * fix crash on auth ## \[0.4.0] * clear cache with reload * add support eSim flag (android) * add maintenance mode ## \[0.3.0] * add new menu style (style\_2) * add progressbar for share event ## \[0.2.0] * add new menu style ## \[0.1.2] * update native sdk dependencies * add show AboutPage flag to config ## \[0.1.1] * add native share modal * fix navigation bar issue on ios # Flutter Source: https://boxo.mintlify.app/changelog/flutter ## 0.18.0 * bump native sdk versions (android 1.45.1, ios 1.29.0) ## 0.17.0 * add orderPaymentId field to Payment ## 0.16.1 * add lottie animation support for miniapp splash loading indicator ## 0.15.0 * remove multitask mode ## 0.14.0 * add splash screen configuration options ## 0.13.1 * saveState is false by default ## 0.13.0 * update native Boxo SDK versions ## 0.12.0 * add setAuthTokens method * update native Boxo SDK versions ## 0.11.0 * update native Boxo SDK versions ## 0.10.0 * update native Boxo SDK versions ## 0.9.0 * update native Boxo SDK versions * fix build errors for android ## 0.8.1 * improvements in native sdk ## 0.8.0 * add native pull to refresh * add camera option to file picker * other improvements in native sdk ## 0.7.0 * add list of user fields to consent screen * Some improvements in native sdk ## 0.6.2 * add new menu style * fix open\_miniapp\_duration on reload ## 0.6.1 - Nov 4, 2024 * no internet connection page * fix crash on auth ## 0.6.0 - Oct 22, 2024 * clear cache with reload * add support eSim flag (android) * add maintenance mode ## 0.5.0 - Oct 14, 2024 * add new menu style (style\_2) * miniapp can open another miniapp with configs * add progressbar to share file ## 0.4.0 - Oct 1, 2024 * add new menu style ## 0.3.0 - Sep 26, 2024 * updated native sdk dependencies * add show About page to config ## 0.2.15 - Sep 24, 2024 * fix device model value \[android] * fix native action bar \[ios] * fix reload \[android] * add native share modal * add saveState param to openMiniapp ## 0.2.11 - Sep 4, 2024 * changed android native sdk to 1.5.17 \[android] ## 0.2.10 - Aug 27, 2024 * add language field to config to pass to miniapp * add file download implementation * save state when user close the miniapp * clear cache and tokens when disabling User Data Sharing * add event to change status bar color ## 0.2.9 - Aug 19, 2024 * changed android native sdk to 1.5.11 \[android] ## 0.2.8 - Aug 17, 2024 * changed android native sdk to 1.5.10 \[android] * removed jcenter ## 0.2.7 - Aug 9, 2024 * play video inline \[ios] ## 0.2.6 - Aug 2, 2024 * close miniapp if webview can't go back on press back button \[ios] * fixed hide/show miniapp \[ios] ## 0.2.5 - Jul 31, 2024 * updated sandbox mode ## 0.2.4 - Jul 31, 2024 * fixed hide all miniapps and reopen last miniapp immediately \[ios] ## 0.2.3 - Jul 26, 2024 * updated network timeouts ## 0.2.2 - Jul 26, 2024 * fix close miniapp page on multitask mode \[android] ## 0.2.1 - Jul 25, 2024 * added consent t\&c and privacy texts ## 0.2.0 - Jul 19, 2024 * Consent Management * added enableSplash flag to miniapp configs * UI changes ## 0.1.17 - Oct 12, 2020 * renamed methods for ios sdk ## 0.1.16 - Oct 8, 2020 * renamed AppboxoSdk class to Appboxo ## 0.1.15 - Oct 8, 2020 * renamed hideAllMiniApps function to hideMiniapps ## 0.1.14 - Sep 21, 2020 * fixed overriding global theme config with empty argument of openMiniapp function * fixed react native channels bug ## 0.1.13 - Sep 17, 2020 * renamed function openMiniApp to openMiniapp * added support dark mode for miniapps ## 0.1.12 - Sep 9, 2020 * added logout() * added single/multitask mode ## 0.1.11 - Sep 3, 2020 * Changed necessary constructor fields for CustomEvent class to required ## 0.1.10 - Sep 3, 2020 * support ios 10 ## 0.1.9 - Jul 13, 2020 * support lifecycle hooks for ios and android * added 'additional\_user\_fields' param to openMiniApp() ## 0.1.7 - Oct 8, 2020 * added hideAllMiniApps() ## 0.1.5 - Jul 2, 2020 * added 'data' param to openMiniApp() * removed openMiniAppWithCustomEvents() ## 0.1.4 - Jul 1, 2020 * support custom events for ios ## 0.1.2 - Jun 29, 2020 * support custom events for Android ## 0.1.0 - May 6, 2020 # iOS SDK Source: https://boxo.mintlify.app/changelog/ios-sdk ## \[1.29.0] - 2026-06-12 ### Added * pass miniapp requiredFields to MiniappDelegate.onAuth * expand AppBoxoWebAppGetMiniappSettings metadata (status, webview\_frame\_size, orientation, action button position/theme, status bar background, miniapp info, hostapp menu style) ## \[1.28.1] - 2026-06-03 ### Fixed * use transactionToken from old JSSDK as a orderPaymentId ## \[1.28.0] - 2026-05-29 ### Added * orderPaymentId to PaymentData ## \[1.27.7] - 2026-05-21 ### Fixed * Bundle for SPM ## \[1.27.6] - 2026-05-15 ### Fixed * Remove cached miniapp settings on logout ## \[1.27.5] - 2026-05-15 ### Added * Lottie progress animation ## \[1.26.1] - 2026-04-27 ### Fixed * Miniapp save state behavior ## \[1.26.0] - 2026-02-27 ### Added * Support location request modal dark mode ## \[1.25.0] - 2026-02-26 ### Added * Support for dark and light splash screen colors ## \[1.24.0] - 2026-02-25 ### Added * Clear local storage keys on miniapp close ## \[1.23.0] - 2026-02-17 ### Added * Request Location and consent screen config from miniapp ## \[1.22.0] - 2026-01-30 ### Added * Config for splash screen color * session\_id for session events ## \[1.21.0] - 2025-11-26 ### Added * style\_5 for ActionButton ### Changed * saveState default value false ## \[1.20.0] - 2025-11-19 ### Fixed * Memory leaks ## \[1.19.1] - 2025-10-31 ### Fixed * Consent Screen multiline texts ## \[1.19.0] - 2025-10-13 ### Added * Open app settings * Get location optimization ## \[1.18.0] - 2025-10-01 ### Added * ConsentScreenConfig ## \[1.17.0] - 2025-09-12 ### Added * Share base64 file ## \[1.16.0] - 2025-09-03 ### Added * Loading progressbar config ## \[1.15.0] - 2025-09-02 ### Added * Remove all miniapp states when changing language ### Fixed * UIKit open url bug ## \[1.14.0] - 2025-08-27 ### Added * support min ios 13.0 * Miniapp async delegate ## \[1.13.0] - 2025-08-20 ### Added * Get miniapp view controller ### Fixed * onPause and onClose lyfecycle events for save state ## \[1.12.0] - 2025-08-19 ### Added * Dark mode progress view ### Fixed * Dark mode status bar ## \[1.11.0] - 2025-08-07 ### Added * setAuthTokens method to miniapp ## \[1.10.3] - 2025-07-31 ### Fixed * Dark mode SSO ### Added * Dark mode logo ## \[1.10.2] - 2025-07-16 ### Fixed * Close miniapp animation ## \[1.10.1] - 2025-04-22 ### Added * Add style option to AppBoxoWebAppSetActionButton ## \[1.10.0] - 2025-04-15 ### Changed * Rename SDK from AppBoxoSDK to BoxoSDK ## \[1.9.3] - 2025-04-10 ### Fixed * White listing url behavior ## \[1.9.2] - 2025-04-10 ### Added * New style\_4 ### Changed * White listed urls validation * Page animation duration 0.3s ### Fixed * QR code scanner ## \[1.9.1] - 2025-04-03 ### Changed * Show detailed error message only for sandbox ## \[1.9.0] - 2025-04-03 ### Added * Miniapp launch animations * session\_start and session\_end analytic events ## \[1.8.5] - 2025-03-26 ### Added * Miniapp slide in animation ### Fixed * Send session analytics * Loading progress animation ## \[1.8.4] - 2025-03-19 ### Added * Pull to refresh ## \[1.8.3] - 2025-03-10 ### Added * Error page close button ## \[1.8.2] - 2025-02-18 ### Added * SSO required fields ## \[1.8.1] - 2025-01-22 ### Changed * Multiline error popup ## \[1.8.0] - 2025-01-09 ### Fixed * Fix deleting cookies and local storage on logout ## \[1.7.7] - 2024-12-15 ### Added * Support LTR/RTL semantic regardless of the hostapp ## \[1.7.6] - 2024-12-02 ### Fixed * String encoding from ascii to utf8 ## \[1.7.5] - 2024-11-21 ### Added * New style\_3 ### Fixed * Reload miniapp ## \[1.7.4] - 2024-10-30 ### Added * open\_miniapp\_duration to GetInitData ### Changed * No internet connection errors ## \[1.7.3] - 2024-10-22 ### Added * Maintenance mode ### Changed * Reload miniapp on clear cache ## \[1.7.2] - 2024-10-16 ### Changed * Miniapp expiration time 1 min * Set reloadIgnoringLocalCacheData URLRequest cachePolicy ## \[1.7.1] - 2024-10-11 ### Added * Loading Indicator for download and share file ### Changed * Update style\_2 more button to gear button ### Fixed * Send sdk version ## \[1.7.0] - 2024-10-09 ### Added * New menu style\_2 * AppBoxoWebAppOpenMiniApp params ### Changed * Removed miniapp settings update timer ### Fixed * Close and open miniapp immediately * Set miniapp delegate on miniapp orientation change * Dismiss popups on orientation change ## \[1.6.0] - 2024-10-01 ### Added * New menu style ## \[1.5.16] - 2024-09-25 ### Added * Added showAboutPage config * Hide action buttons * Miniapp urlSuffix ## \[1.5.15] - 2024-09-23 ### Fixed * WebView top padding ## \[1.5.14] - 2024-09-20 ### Added * Share file ### Changed * Revert: Share file instead open File manager on download file ## \[1.5.13] - 2024-09-19 ### Changed * Share file instead open File manager on download file ## \[1.5.12] - 2024-09-13 ### Added * Miniapp saveState config ## \[1.5.11] - 2024-08-26 ### Added * Download file event ### Fixed * Change status bar color ## \[1.5.10] - 2024-08-22 ### Added * Add language field to Config * Add change status bar color * Clear cache and token when disable user consent ## \[1.5.9] - 2024-08-20 ### Changed * Save miniapp state on close miniapp ## \[1.5.8] - 2024-08-09 ### Added * allowsInlineMediaPlayback true ## \[1.5.7] - 2024-07-31 ### Change * CLose miniapp on back button press * Hide/show miniapps refactored ## \[1.5.6] - 2024-07-31 ### Change * Sandbox mode and staging ## \[1.5.5] - 2024-07-31 ### Added * Esim direct install ### Fixes * Hide all miniapps and reopen last miniapp immediately ## \[1.5.4] - 2024-07-25 ### Added * Consent links * apply primary color for SSO allow button ## \[1.5.3] - 2024-07-23 ### Changed * Sentry endpoint ## \[1.5.2] - 2024-07-17 ### Fixes * system info data ## \[1.5.1] - 2024-07-16 ### Added * enableSplash option to miniapp config ### Changed * Remove miniapp state on close miniapp ## \[1.5] - 2024-07-15 ### Changed * System info: model ## \[1.4.27] - 2024-07-09 ### Fixed * Settings: Camera icon ## \[1.4.26] - 2024-07-09 ### Added * Consent Management ### Changed * Increase miniapp menu button size ## \[1.4.25] - 2024-06-07 ### Fixed * Don't clear miniapp states on hideAllMiniapp ## \[1.4.24] - 2024-06-03 ### Added * SSO allow haptic feedback ## \[1.4.23] - 2024-05-07 ### Added * Prepare miniapps ## \[1.4.22] - 2024-04-17 ### Changed * Revert Hide splash screen when webview starts loading ## \[1.4.21] - 2024-04-16 ### Changed * Hide SSO loading progress * Hide splash screen when webview starts loading ## \[1.4.20] - 2024-03-27 ### Added * miniappSettingsExpirationTime field to Config ## \[1.4.19] - 2024-03-22 ### Added * Cache miniapp settings with completion handler ## \[1.4.18] - 2024-03-19 ### Added * Cache miniapp settings ## \[1.4.17] - 2024-02-27 ### Changed * Remove user info permission * Remove miniapp state on call close ### Fixed * Call completionHandler for runJavaScriptAlertPanelWithMessage ## \[1.4.16] - 2024-02-17 ### Fixed * SSO modal ## \[1.4.15] - 2024-02-15 ### Changed * Powered by boxo logo * Hide loader view on half web content loaded * SSO modal ### Fixed * Image caching ## \[1.4.14] - 2023-12-15 ### Added * User agent * Safe area size ## \[1.4.13] - 2023-11-15 ### Fixed * Action button size ## \[1.4.12] - 2021-11-16 ### Changed * Build sdk with Xcode 11.7 version ## \[1.4.11] - 2021-11-15 ### Fixed * logout on miniapp is not open ## \[1.4.10] - 2021-11-15 ### Added * showClearCache option ### Changed * Powered by appboxo icon ### Fixed * Hide miniapps on logout ## \[1.4.9] - 2021-10-08 ### Fixed * Update miniapp settings every 30 sec ## \[1.4.8] - 2021-09-21 ### Added * onUserInteraction method to miniapp delegate * Show js prompts * Clear cookies & local storage on clear cache ### Changed * Simplify miniapp menu ### Fixed * Hide branding * About page constraints ## \[1.4.7] - 2021-09-13 ### Fixed * clear cookies and local storage on logout ## \[1.4.6] - 2021-08-06 ### Added * permissionsPage option to hide Settings menu ### Changed * dismiss cookies and local storage on clear cache ## \[1.4.5] - 2021-08-03 ### Fixed * Show logo in confirm view * Status bar color ## \[1.4.4] - 2021-07-21 ### Added * Pull miniapp settings every 30 seconds and reload if needed ## \[1.4.3] - 2021-07-02 ### Added * New webview allow/cancel request delegate method * is\_shopboxo field ### Fixed * Action button top anchor for ios 11 ## \[1.4.2] - 2021-06-18 ### Changed * isSandbox field renamed to sandboxMode in Config * Payment flow * Custom event redesigned ## \[1.4.1] - 2021-06-15 ### Changed * Auth flow * Auto orientation ## \[1.4.0] - 2021-05-27 ### Added * Get approved miniapps * Hide branding option * Inject js script ## \[1.3.39] - 2021-03-17 ### Added * Hide/show appboxo branding * Disable whitelisting urls ### Fixed * Recaptha * Support multiple window mode for auth with socials ## \[1.3.38] - 2021-03-01 ### Added * Sentry ### Changed * Removed params from getMiniapp method * Added new methods to Miniapp to setting auth payload, additional user data, custom data ### Fixed * Open new tab requests ## \[1.3.37] - 2021-01-25 ### Fixed * Whitelisted urls * Json response with dictionary * Handle request errors * MiniappConfig refactored ## \[1.3.36] - 2020-12-18 ### Added * url change handler * option to add third action menu * extra query parameters to miniapp URL ## \[1.3.35] - 2020-11-18 ### Added * Payment method ## \[1.3.34] - 2020-09-30 ### Fixed * Border for fixed action buttons view ## \[1.3.33] - 2020-09-29 ### Changed * Login error body ### Fixed * Http Content-type header ## \[1.3.32] - 2020-09-24 ### Changed * Classes renamed ### Fixed * Action buttons constraints ## \[1.3.31] - 2020-09-15 ### Added * Support dark mode ## \[1.3.30] - 2020-09-11 ### Added * Support ios simulator ## \[1.3.29] - 2020-09-09 ### Added * Design for Dark mode * Show miniapp name on popup menu ## \[1.3.28] - 2020-09-03 ### Added * Dynamic floating action menu * Allow swipe back for webview * Enable select text in webview ## \[1.3.27] - 2020-09-03 ## \[1.3.26] - 2020-09-03 ### Changed * Support ios 10 ## \[1.3.25] - 2020-08-24 ### Fixed * Open miniapp from miniapp ## \[1.3.24] - 2020-08-24 \###Changed * Minimal support ios 11 ### Fixed * Miniapp lifecycle ## \[1.3.23] - 2020-08-21 ### Added * support ios 9 * additional user fields for auth in miniapps ### Changed * data field in miniapp from string to map ## \[1.3.21] - 2020-07-30 ### Added * added miniapp lifecycle ### Changed * changed License to Apache 2.0 ## \[1.3.20] - 2020-07-28 ## \[1.3.19] - 2020-07-28 ## \[1.3.18] - 2020-07-22 ### Added * added login/logout and transaction tracking in sdk * added white\_listed\_urls in miniapp settings to filter miniapp domains * added auth header on fetching miniapp settings ## \[1.3.16] - 2020-07-09 ### Added * Hide all opened miniapps * Error message handler on fetch miniapp settings ## \[1.3.15] - 2020-06-18 ## \[1.3.14] - 2020-06-18 ### Added * Objective-C support ## \[1.3.13] - 2020-06-12 ### Added * Miniapp session analytics * Hostapp colors * Handle sms,tel,mail url schemes ### Changed * js body for AppBoxoWebAppGetMiniappSettings method ### Fixed * Update opened miniapp payload * Retry load current page ## \[1.3.11] - 2020-05-28 ### Added * AppBoxoWebAppOnRestore feature ### Changed * Deploy.yml ## \[1.3.9] - 2020-05-22 ### Added * Miniapp settings * Compass * Instant miniapp reopening * Background color of the window ### Changed * AppBoxoWebAppShowImages result callback return type * Render NavBar only when miniapp is loaded ### Fixed * Landscape mode ## \[1.3.8] - 2020-05-14 ### Added * Gyroscope * Accelerometer * Status bar color based on miniapp settings * CHANGELOG ### Fixed * Loader view for landscape mode # React Native Source: https://boxo.mintlify.app/changelog/react-native-sdk ## \[1.15.2] * bump native android sdk version to 1.45.1 ## \[1.15.1] * bump native sdk versions (android - 1.44.0, ios - 1.29.0) ## \[1.14.0] * add orderPaymentId field to Payment ## \[1.13.1] * add lottie animation support for miniapp splash loading indicator ## \[1.12.0] * remove multitask mode ## \[1.11.0] * add splash screen configuration options ## \[1.10.0] * saveState is false by default * android: add esim direct install * add style\_5 for ActionButtons ## \[1.9.0] * added setAuthTokens function * updated native sdk versions ## \[1.8.0] * update android native sdk ## \[1.7.2] * update android native sdk * fix exports ## \[1.7.1] * improvements in native sdk ## \[1.7.0] * add miniapp page animation * add native pull to refresh * add camera option to file picker * other improvements in native sdk ## \[1.6.0] * Added list of user fields to consent screen * LTR/RTL support by language * Some improvements in native sdk ## \[1.5.2] - 2024-11-21 * add new menu style * fix send payment result(android) ## \[1.5.1] - 2024-11-04 * no internet connection page * fix crash on auth ## \[1.5.0] - 2024-10-22 * add support eSim flag (android) * add maintenance mode ## \[1.4.0] - 2020-10-21 * add new menu style (style\_2) * added progressbar for share event * add miniapp settings expiration time to configs * reload after clear cache ## \[1.3.0] - 2024-10-01 * add new menu style ## \[1.2.0] - 2024-09-26 * add aboutPage flag to config * update native sdk dependencies ## \[1.1.3] - 2024-09-20 * add share modal * fix action bar on ios * fix device model name on android ## \[1.1.2] - 2024-09-13 * add saveState param to openMiniapp ## \[1.1.1] - 2024-09-20 * add enableSplash param to openMiniapp ## \[1.1.0] - 2024-08-20 * native android sdk ver. 1.5.16 * native ios sdk ver. 1.5.11 * add Consent Management * add language support * add sandbox mode * save state when user close the miniapp ## \[1.0.40] - 2023-11-24 * native ios sdk ver. 1.4.13 * native android sdk ver. 1.4.21 # Boxo Connect Source: https://boxo.mintlify.app/host-apps/BoxoConnect ## Introduction Boxo Connect is a **Single Sign-On (SSO)** functionality that enables the host app to securely pass user profile information, allowing seamless authorization within the mini app. In essence, the Boxo Platform facilitates the transfer of user data from the host app backend to the mini app backend, ensuring smooth user authentication and returning a session token for continued access. This is the traditional OAuth flow where the host app backend provides auth codes and access tokens to the Boxo Platform. Here is diagram showcasing the hostapp user authorization inside miniapp AuthDiagram Authentication and User Authorization Flow The user opens the host app and launches the mini app. To proceed, the user must be identified (e.g., for product purchases or user registration). The mini app calls `Boxo.login()`. The user is prompted to confirm access to their personal data required for authorization. The Boxo native SDK retrieves an authorization code from the host app and sends an HTTPS request to the Boxo platform. The Boxo platform forwards the authorization code via an HTTPS request to the host app backend. The host app backend validates the authorization code and returns an access token. The Boxo platform sends an HTTPS request with the access token to the host app backend to retrieve user data. The host app backend validates the access token and returns user data. The Boxo platform forwards the user data via an HTTPS request to the mini app backend. The mini app backend registers a new user or identifies an existing one, then issues an authorization token to the Boxo platform. The Boxo platform returns the authorization token to the Boxo native SDK. The authorization token is passed to the mini app. The mini app sends a request with the authorization token to the mini app backend to retrieve user data. The mini app backend validates the authorization token and returns the user data. The user is successfully authorized and can proceed within the mini app. \*Note: Feature must be enabled in [Dashboard Partnership](https://dashboard.boxo.io/partnerships/) AuthDiagram **Data format** Currently, data exchange is conducted in JSON format. String size limits are defined within the respective data types. This endpoint allows the Boxo platform to obtain an access token in exchange for an authorization code. **URL and METHOD** This endpoint must handle a HTTPS POST request URL to endpoint must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) AuthDiagram **Headers** | Key | Value | | ------------------- | ----------------------------------------------------------------- | | Authorization | ` ` | | X-Miniapp-App-ID | `` | | X-Hostapp-Client-ID | `` | * Default ``: Token. Access token prefix can be set in [Boxo Connect](https://dashboard.boxo.io/host-apps/). * `hostapp_client_id` and `hostapp_secret_key` must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) **Body** | Field | Data type | Description | | ---------- | --------- | ----------------------------------------- | | auth\_code | String | Auth code provided by hostapp to Boxo SDK | **Response** * Response status must be `200` in all cases * Response body: | Field | Data type | Optional | Description | | --------------- | ------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `access_token` | String(1000) | No, except `error_code` provided | Access token for get user data request. To use in payments requests enable `Use access token` in [Boxo Payments](https://dashboard.boxo.io/host-apps/). | | `refresh_token` | String(1000) | Yes | Refresh token for get user data request. To use in payments requests enable `Use access token` in [Boxo Payments](https://dashboard.boxo.io/host-apps/). | | `error_code` | String | Yes | If some error is occured error code should be provided. Example: `{"error_code": "INVALID_AUTH_CODE"}` All error codes can be found [here](/host-apps/ErrorCodes) | **Request Example:** ```text theme={"system"} curl --location --request POST '[YOUR_SERVER_URL]/api/get_access_token/' \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \ --data-raw '{ "auth_code": "{{HOSTAPP_AUTH_CODE_THAT_COMES_FROM_SDK}}" }' ``` This endpoint allows the Boxo platform to retrieve user data using an access token. **URL and METHOD** * This endpoint must handle a HTTPS GET request * URL to endpoint must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) AuthDiagram **Headers** | Key | Value | | --------------------- | ---------------------------------- | | `Authorization` | `Token ` | | `X-Miniapp-App-ID` | ` ` | | `X-Hostapp-Client-ID` | `` | **Response:** * Response status must be `200` in all cases * Response body: | Field | Data type | Optional | Description | | ------------ | --------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `user_data` | UserData | No, except `error_code` provided | Hostapp user data. | | `error_code` | String | Yes | If some error is occured error code should be provided. Example: `{"error_code": "INVALID_ACCESS_TOKEN"}` All error codes can be found [here](/host-apps/ErrorCodes) | **UserData** | Field | Data type | Optional | Description | | ------------------- | ----------- | -------- | ------------------------------------------ | | `reference` | String(100) | | Reference to user in Hostapp Server | | `email` | String | Yes | Verified user email address | | `phone` | String | Yes | Verified user phone number in E.164 format | | `first_name` | String | Yes | User's first name | | `last_name` | String | Yes | User's last name | | `custom_attributes` | JSON | Yes | Custom attributes | **WARNING** For Shopboxo miniapps either `email` or `phone` must be provided **Request Example:** ```text theme={"system"} curl --location --request GET '[YOUR_SERVER_URL]/api/get_user_data/'\ --header 'Content-Type: application/json' \ --header 'Authorization: Token {{ACCESS_TOKEN}}' ``` **Required fields** Each mini app requires a set of minimum fields to create a user within its system and generate a session for the newly created user. The specific required fields for each mini app can be found in its details on the Showroom page. Below is a list of all possible fields: * email * phone * first\_name * last\_name **Initialization** Parameter Descriptions: Within the SDK, there are specific parameters and methods that must be either provided or implemented to ensure proper functionality. `app_id` - Boxo miniapp app id To launch a specific mini app, you must first call the initialization method. ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") miniapp.delegate = self miniapp.open(viewController: self) ... extension ViewController : MiniappDelegate { func onAuth(miniapp: Miniapp) { //get AuthCode from hostapp backend and send it to miniapp miniapp.setAuthCode(authCode: "auth_code") } } ``` ```kotlin theme={"system"} val miniapp = Boxo.getMiniapp("app_id") miniapp.setAuthListener { _, miniapp -> //get AuthCode from hostapp backend and send it to miniapp miniapp.setAuthCode("auth_code") } miniapp.open() ``` ```dart theme={"system"} Boxo.openMiniapp('app_id'); Boxo.lifecycleHooksListener( onAuth: (appId) { // called when authorization flow starts //get AuthCode from hostapp backend and send it to miniapp Boxo.setAuthCode('app_id', 'auth_code'); } ); ``` ```js theme={"system"} Boxo.openMiniapp('app_id') Boxo.lifecycleHooksListener({ onAuth: (appId: string) => { //get AuthCode from hostapp backend and send it to miniapp Boxo.setAuthCode('app_id', 'auth_code'); }, }); ``` ```js theme={"system"} Boxo.openMiniapp({ appId: 'app_id'}); Boxo.addListener('miniapp_lifecycle', event => { if (event.lifecycle == 'onAuth') { //get AuthCode from hostapp backend and send it to miniapp Boxo.setAuthCode({ appId: 'app_id', 'auth_code'}); } }); ``` ```js theme={"system"} Boxo.openMiniapp({ appId: 'app_id' }) Boxo.addAuthListener((authEvent) => { //get AuthCode from hostapp backend and send it to miniapp Boxo.setAuthCode('app_id', 'auth_code') }); ``` **WARNING** When a user logs out of the host app, ensure that the WebView cache is cleared using the following commands: `Boxo.logout()` for Android or `Boxo.shared.logout()` for iOS so that the miniapps' storage is also cleared to log out the miniapp users as well. This is Boxo endpoint to get status of user consent in Boxo Platform **URL and METHOD** * This is HTTPS GET `/api/v1/accounts/consent/get_consent/` endpoint ### Query Parameters: | Parameter | Data type | Optional | Description | | ---------------- | --------- | -------- | ----------------------------------- | | `client_id` | String | | Hostapp identifier | | `app_id` | String | | Miniapp identifier | | `user_reference` | String | | Reference to user in Hostapp Server | **Response:** ```text theme={"system"} { "is_consented": } ``` This is the streamlined Direct flow where the host app backend directly sends user data to the Boxo Platform. Here is diagram showcasing the hostapp user authorization inside miniapp AuthDiagram Authentication and User Authorization Flow The user opens the host app and launches the miniapp. The miniapp determines that user identification is needed to proceed. The miniapp calls `appboxosdk.login` JS SDK event to request login action. The user sees a consent dialog asking to "Allow miniapp to access your account information" with an "Allow" button. After user consent, the system makes a request to the host app's authentication gateway. The host app backend sends the user data to the Boxo Platform **connect/** endpoint. The Boxo Platform forwards the user data to the miniapp backend. The miniapp backend processes the user data and generates an authorization token. The token is also provided back to the host app. The authorization token is sent back through the chain to the miniapp frontend. The miniapp server authorizes the user using the token. The user is successfully authorized and can continue using the miniapp. This process ensures a secure and seamless flow for user authorization between the host app, Boxo platform, and miniapp. \*Note: Feature must be enabled in [Dashboard Partnership](https://dashboard.boxo.io/partnerships/) AuthDiagram **Data format** Currently, data exchange is conducted in JSON format. String size limits are defined within the respective data types. This endpoint is called by the Super App (partner) server to connect a user to a miniapp on the Boxo Platform. On success, it returns an authorization token pair for the miniapp session. **URL and METHOD** * HTTPS POST `/api/v1/connect/` (Boxo Platform) **Headers** | Key | Value | | ------------ | ------------------ | | Content-type | `application/json` | > Authentication to this endpoint is managed via your partnership configuration in the Dashboard (e.g., IP whitelisting or [Request Signaturing](/host-apps/Signaturing)). Follow your integration setup. **Request Body** | Field | Data type | Optional | Description | | ----------- | --------- | -------- | ----------------------- | | `client_id` | String | No | Hostapp identifier | | `app_id` | String | No | Miniapp identifier | | `user_data` | UserData | No | User information object | **UserData** | Field | Data type | Optional | Description | | ------------------- | --------- | -------- | ------------------------------------------ | | `reference` | String | No | Reference to user in Hostapp Server | | `email` | String | Yes | Verified user email address | | `phone` | String | Yes | Verified user phone number in E.164 format | | `first_name` | String | Yes | User's first name | | `last_name` | String | Yes | User's last name | | `custom_attributes` | JSON | Yes | Custom attributes | **Response** * Response status `200` for success, `400` for errors * Response body: **Success Response (200):** | Field | Data type | Description | | --------------- | --------- | ------------- | | `token` | String | Auth token | | `refresh_token` | String | Refresh token | **Error Response (400):** | Field | Data type | Optional | Description | | ------------------- | --------- | -------- | ------------------------------ | | `error_code` | String | No | Error code | | `error_message` | String | No | Detailed error message | | `exception` | String | Yes | Exception details if available | | `custom_attributes` | Object | Yes | Additional error context | **Request Example** ```text theme={"system"} curl --location --request POST '[BOXO_PLATFORM_SERVER_URL]/api/v1/connect/' \ --header 'Content-Type: application/json' \ --data-raw '{ "client_id": "{{CLIENT_ID}}", "app_id": "{{MINIAPP_ID}}", "user": { "reference": "{{USER_REFERENCE}}", "email": "john@example.com", "phone": "+11234567890", "first_name": "John", "last_name": "Doe", "custom_attributes": {} } }' ``` **WARNING** For Shopboxo miniapps either `email` or `phone` must be provided **Success Response (200)** ```text theme={"system"} { "token": "", "refresh_token": "" } ``` **Error Response (400)** ```text theme={"system"} { "error_code": "INVALID_INPUT", "error_message": "Missing required field: app_id", "exception": null, "custom_attributes": null } ``` **Required fields** Each mini app requires a set of minimum fields to create a user within its system and generate a session for the newly created user. The specific required fields for each mini app can be found in its details on the Showroom page. Below is a list of all possible fields: * email * phone * first\_name * last\_name * custom\_attributes **Initialization** Parameter Descriptions: Within the SDK, there are specific parameters and methods that must be either provided or implemented to ensure proper functionality. `app_id` - Boxo miniapp app id To launch a specific mini app, you must first call the initialization method. ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") miniapp.delegate = self miniapp.open(viewController: self) ... extension ViewController : MiniappDelegate { func onAuth(miniapp: Miniapp) { //send a request to backend to fetch tokens miniapp.setAuthTokens(["token" : "", "refresh_token" : ""]) } } ``` ```kotlin theme={"system"} val miniapp = Boxo.getMiniapp("app_id") miniapp.setAuthListener { _, miniapp -> //send a request to backend to fetch tokens miniapp.setAuthTokens(mapOf( "token" to "", "refresh_token" to "" )) } miniapp.open() ``` ```dart theme={"system"} Boxo.openMiniapp('app_id'); Boxo.lifecycleHooksListener( onAuth: (appId) { // called when authorization flow starts //send a request to backend to fetch tokens Boxo.setAuthTokens({ 'token': '', 'refresh_token': '' }); } ); ``` ```js theme={"system"} Boxo.openMiniapp('app_id') Boxo.lifecycleHooksListener({ onAuth: (appId: string) => { //send a request to backend to fetch tokens Boxo.setAuthTokens({ 'token': '', 'refresh_token': '' }); }, }); ``` **WARNING** When a user logs out of the host app, ensure that the WebView cache is cleared using the following commands: `Boxo.logout()` for Android or `Boxo.shared.logout()` for iOS so that the miniapps' storage is also cleared to log out the miniapp users as well. This is Boxo endpoint to get status of user consent in Boxo Platform **URL and METHOD** * This is HTTPS GET `/api/v1/accounts/consent/get_consent/` endpoint ### Query Parameters: | Parameter | Data type | Optional | Description | | ---------------- | --------- | -------- | ----------------------------------- | | `client_id` | String | | Hostapp identifier | | `app_id` | String | | Miniapp identifier | | `user_reference` | String | | Reference to user in Hostapp Server | | **Response:** | | | | ```text theme={"system"} { "is_consented": } ``` # Boxo Payments Source: https://boxo.mintlify.app/host-apps/BoxoPayments ## Introduction Boxo Payments is an in-app payment functionality that enables host app users to complete payments for orders within the miniapp. Here is a diagram illustrating the payment process for a miniapp order using the host app's payment system. AuthDiagram The user navigates to the payment page in the miniapp and initiates the creation of an order. The miniapp server creates the order and sends a **createOrderPayment** request to the Boxo Platform. The Boxo Platform initiates the order payment process on the host app server. The host app server returns an **orderPaymentID** to the Boxo Platform. The Boxo Platform then forwards the **orderPaymentID** to the miniapp server. The miniapp server passes the **orderPaymentID** to the miniapp. The miniapp forwards the **orderPaymentID** to the Boxo JS SDK's `pay` method. The **Boxo Native SDK** captures the Boxo JS SDK's pay event (with the **orderPaymentID**) and displays a payment confirmation page to the user. The user confirms the payment. The host app processes the payment and sends the payment status as a response to the Boxo JS SDK pay event. * During this process, the host app server sends a callback to the Boxo Platform, which updates the order status in the miniapp backend. The miniapp processes the payment status received from the Boxo JS SDK event and confirms the order payment status on its server. The miniapp finalizes the order payment status. * If the order is still processing at this stage, the miniapp will request the payment status from the Boxo Platform, which, in turn, will query the host app server for an update. Finally, the miniapp displays the order payment status page to the user. \*Note: Feature must be enabled in [Dashboard Partnership](https://dashboard.boxo.io/partnerships/) AuthDiagram **Data format** Currently, JSON is used for data exchange. Decimal values can be represented as floats, numbers, or strings, with a maximum of 20 digits in total and up to 2 digits after the decimal point. String size limits are defined within the data type specifications. This endpoint allows the Boxo Platform to create an order payment (refer to Step 3 in the diagram). **URL and METHOD:** This endpoint must handle a HTTPS POST request URL to endpoint must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) AuthDiagram **Headers:** | Key | Value | | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Authorization` | ` ` or token from [Get access token](/host-apps/BoxoConnect#get-access-token) can be used instead | | `Content-type` | `application/json` | | `X-User-ID` | `` | * Default ``: `Token`. Access token prefix can be set in [Boxo Connect](https://dashboard.boxo.io/host-apps/). * To use user access token from Boxo Connect as authorization token enable `Use access token` in [Dashboard](https://dashboard.boxo.io/host-apps/). * `hostapp_client_id` and `hostapp_secret_key` must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) **Body** | Field | Data type | Description | | -------- | ------------ | -------------------------------------- | | `app_id` | String | Miniapp identifier | | `order` | OrderDetails | Order info (amount, currency and etc.) | **OrderDetails:** | Field | Data type | Optional | Description | | -------------------------- | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `currency` | String(20) | No | Currency code for the order (e.g., 'USD') | | `amount` | Decimal | No | Total order amount (decimal with 2 decimal places) | | `subtotal_amount` | Decimal | Yes | Subtotal before taxes and shipping (decimal with 2 decimal places) | | `shipping_amount` | Decimal | Yes | Shipping cost (decimal with 2 decimal places) | | `discount_amount` | Decimal | Yes | Total discount applied (decimal with 2 decimal places) | | `tax_title` | String(250) | Yes | Title/name of the tax | | `tax_amount` | Decimal | Yes | Tax amount (decimal with 2 decimal places) | | `taxes_included` | Boolean | Yes | Boolean indicating if taxes are included in the price | | `wholesale_total` | Decimal | Yes\* | Wholesale/settlement amount of the order, deducted from the partner team balance when the order is paid. Sent as provided by the miniapp and omitted when the miniapp does not provide it. \***Always present for partner teams on the [pre-paid model](#pre-paid-model)** | | `wholesale_total_currency` | String(20) | Yes | Currency of `wholesale_total`. Sent as provided by the miniapp and omitted when the miniapp does not provide it; the team balance currency is used for the deduction in that case | | `note` | Text | Yes | Additional notes for the order | | `custom_attributes` | JSON | Yes | JSON field for custom order attributes | | `miniapp_order_id` | String(255) | Yes | Order ID from the miniapp side | | `hostapp_user_id` | String(255) | Yes | User ID from the host app | | `items` | OrderItem\[] | Yes | List of order items (see OrderItem below) | | `shipping_address` | Object | Yes | Shipping address details (see OrderShippingAddress below) | **OrderItem:** | Field | Data type | Optional | Description | | ---------------------- | ----------- | -------- | ------------------------------------------------- | | `product_name` | String(250) | No | Name of the product | | `product_variant_name` | String(250) | No | Product variant name | | `product_sku` | String(250) | No | Product SKU/identifier | | `product_image_url` | String(500) | No | URL to product image | | `quantity` | Integer | No | Quantity of the product (positive integer) | | `price` | Decimal | No | Price per item (decimal with 2 decimal places) | | `discount` | Decimal | No | Discount per item (decimal with 2 decimal places) | **OrderShippingAddress:** | Field | Data type | Optional | Description | | --------------- | ------------ | -------- | ----------------------------------------------------- | | `address1` | String(1000) | Yes | Primary address line | | `address2` | String(1000) | Yes | Secondary address line | | `first_name` | String(250) | Yes | First name | | `last_name` | String(250) | Yes | Last name | | `phone` | String(250) | Yes | Phone number | | `region_name` | String(100) | Yes | Region/state name | | `region_code` | String(100) | Yes | Region/state code | | `province_name` | String(250) | Yes | Province name | | `province_code` | String(250) | Yes | Province code | | `city` | String(250) | Yes | City name | | `country` | String(250) | Yes | Country name | | `postal_code` | String(250) | Yes | Postal/ZIP code | | `latitude` | Decimal | Yes | Geographic latitude (-90 to 90, 15 decimal places) | | `longitude` | Decimal | Yes | Geographic longitude (-180 to 180, 15 decimal places) | **Response:** * Response status must be `200` in all cases * Response body: | Field | Data type | Optional | Description | | ------------------- | ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `order_payment_id` | String(250) | No, except `error_code` provided | Order payment identifier | | `error_code` | String | Yes | If some error is occured error code should be provided. Example: `{"error_code": "INVALID_ORDER_DATA"}` All error codes can be found [here](/host-apps/ErrorCodes) | | `custom_attributes` | JSON | Yes | JSON field for custom order attributes | **Request Example:** ``` curl --location --request POST '[YOUR_SERVER_URL]/api/create-order-payment/'\ --header 'Content-Type: application/json' \ --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \ --data-raw '{ "app_id": "{{MINIAPP_ID}}", "order": { "amount": "100.00", "currency": "USD", "miniapp_order_id": "{{ MINIAPP_ORDER_ID }}", "hostapp_user_id": "{{ HOSTAPP_USER_ID }}" }}' ``` This endpoint is for Boxo platform to get order payment status **URL and METHOD** This endpoint must handle a HTTPS POST request Can be configured to be a GET method URL to endpoint must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) AuthDiagram **Headers** | Key | Value | | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Authorization` | ` ` or token from [Get access token](/host-apps/BoxoConnect#get-access-token) can be used instead | | `Content-type` | `application/json` | | `X-User-ID` | `` | Default ``: `Token`. Access token prefix can be set in [Boxo Connect](https://dashboard.boxo.io/host-apps/). To use user access token from Boxo Connect as authorization token enable `Use access token` in [Dashboard](https://dashboard.boxo.io/host-apps/). `hostapp_client_id` and `hostapp_secret_key` must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) **Body** | Field | Data type | Description | | ------------------ | --------- | ------------------------ | | `app_id` | String | Miniapp identifier | | `client_id` | String | Hostapp identifier | | `order_payment_id` | String | Order payment identifier | **Response** * Response status must be `200` in all cases * Response body | Field | Data type | Optional | Description | | --------------------- | ----------- | :------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `app_id` | String | No, except `error_code` provided | Miniapp identifier | | `client_id` | String | No, except `error_code` provided | Hostapp identifier | | `order_payment_id` | String | No, except `error_code` provided | Order payment identifier | | `payment_status` | String(100) | No, except `error_code` provided | Order payment status: `in_process`, `paid`, `cancelled`, `failed` | | `payment_fail_reason` | String | Yes | Order payment fail reason | | `custom_attributes` | JSON | Yes | JSON field for custom order attributes | | `error_code` | String | Yes | If some error is occured error code should be provided. Example: `{"error_code": "ORDER_NOT_FOUND"}` All error codes can be found [here](/host-apps/ErrorCodes) | **Request Example** ``` curl --location --request POST '[YOUR_SERVER_URL]/api/get-order-payment-status/'\ --header 'Content-Type: application/json' \ --header 'Authorization: Basic {{BASE64_ENCODED_CLIENT_ID_AND_CLIENT_SECRET}}' \ --data-raw '{ "app_id": "{{MINIAPP_ID}}", "client_id": "{{CLIENT_ID}}", "order_payment_id": "{{ORDER_PAYMENT_ID}}"}' ``` This endpoint is part of the Boxo Platform. It sends a request to the miniapp server to complete the order payment after the payment has been processed (refer to the step after 10 in the diagram). **URL and METHOD** This is HTTPS POST `/api/v1/orders/complete-order/` endpoint IP address of requesting services must be provided in [Dashboard](https://dashboard.boxo.io/host-apps/) for whitelisting or [Request Signaturing](/host-apps/Signaturing) must be enabled **Headers** | Key | Value | | ------------ | ---------------- | | Content-type | application/json | **Body** | Field | Data type | Optional | Description | | --------------------- | ----------- | -------- | ----------------------------------------------------------------- | | `order_payment_id` | String(250) | No | Order payment identifier | | `app_id` | String | No | Miniapp identifier | | `client_id` | String | No | Hostapp identifier | | `payment_status` | String(100) | No | Order payment status: `in_process`, `paid`, `cancelled`, `failed` | | `payment_fail_reason` | String | Yes | Order payment fail reason | | `custom_attributes` | JSON | Yes | Order custom attributes | **Response:** * Response status will be `400` in case there is error\_code * Response body: | Field | Data type | Description | | -------------- | --------- | -------------------------------------------------------------------------------- | | code | String | Request result code example: `SUCCESS` | | message | String | Result message | | error\_code | String | Error code | | error\_message | String | Result error message. All error codes can be found [here](/host-apps/ErrorCodes) | **Request Example** ``` curl --location --request POST '[BOXO_PLATFORM_SERVER_URL]/api/v1/orders/complete-order/' \ --header 'Content-Type: application/json' \ --data-raw '{ "order_payment_id": "{{ORDER_PAYMENT_ID}}", "payment_status": "paid", "client_id": "{{CLIENT_ID}}", "app_id": "{{MINIAPP_ID}}" }' ``` **Response Example** ``` { "code": "SUCCESS", "message": "Success" } ``` ``` { "error_code": "ORDER_NOT_FOUND", "error_message": "No Order matches the given query." } ``` ## Pre-paid model Platform partners can operate on a pre-paid basis. The partner team keeps a pre-paid balance with Boxo (topped up via wire transfer or crypto payment), and each paid order settles against that balance: 1. The pre-paid model is enabled for the partner team's organization (managed by Boxo). 2. Miniapps include `wholesale_total` (and optionally `wholesale_total_currency`) in each create order payment request. The platform rejects orders without it (`WHOLESALE_TOTAL_REQUIRED`) and orders exceeding the remaining balance (`INSUFFICIENT_BALANCE`). 3. When an order reaches the `paid` status, `wholesale_total` is deducted from the team balance. The balance is deducted only for orders created by Boxo miniapps on **production** host apps — staging host apps never deduct the balance. ### Free orders without confirmation Separately from the balance flow, a team-level setting `free_orders_without_confirmation` is available (managed by Boxo). It is a requirement for the pre-paid model: * When enabled, orders created with `amount` = `0.00` are marked as `paid` on creation. * Your create order payment endpoint is still called as usual and must return an `order_payment_id`, but the platform does not wait for your payment confirmation (webhook or status poll) for these orders. * The pre-paid balance deduction of `wholesale_total` still applies to such orders. Listening for Payment event ```swift theme={"system"} miniapp.delegate = self ... extension ViewController : MiniappDelegate { func didReceivePaymentEvent(miniapp: Miniapp, paymentData: PaymentData) { // Show payment processing screen and handle payment according to paymentData // paymentData.amount // paymentData.miniappOrderId // paymentData.currency // paymentData.orderPaymentId // Once payment is done, modify payment data and send result to mini app: paymentData.status = "success" // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled miniapp.sendPaymentEvent(paymentData: paymentData) } } ``` Kotlin ```kotlin theme={"system"} Boxo.getMiniapp("[APP_ID]") .setPaymentEventListener { _, miniapp, paymentData -> // Show payment processing screen and handle payment according to paymentData // paymentData.amount // paymentData.miniappOrderId // paymentData.currency // paymentData.orderPaymentId // Once payment is done, modify payment data and send result to mini app: paymentData.status = "success" // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled miniapp.sendPaymentResult(paymentData) }.open() ``` ```dart theme={"system"} @override void initState() { paymentSubscription = Boxo.paymentEvents().listen((PaymentEvent payment) async { Boxo.hideMiniapps(); // need to hide the miniapp before showing the payment page or popup // Show payment processing screen and handle payment according to paymentData // payment.amount // payment.miniappOrderId // payment.currency // payment.orderPaymentId // Once payment is done, modify payment data and send result to miniapp: NDialog( dialogStyle: DialogStyle(titleDivider: true), title: Text("Payment"), content: Text("Confirm payment"), actions: [ TextButton( child: Text("Confirm"), onPressed: () { Navigator.pop(context); //.. send request to handle payment to your backend payment.status = 'success'; // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled Boxo.sendPaymentEvent(payment); // send payment result to miniapp Boxo.openMiniapp(payment.appId); // need to open the miniapp }), TextButton( child: Text("Cancel"), onPressed: () { Navigator.pop(context); payment.status = 'cancelled'; Boxo.sendPaymentEvent(payment); Boxo.openMiniapp(payment.appId); }), ], ).show(context); }); Boxo.openMiniapp('[APP_ID]'); super.initState(); } ``` ```js theme={"system"} useEffect(() => { const paymentEventsSubscription = Boxo.paymentEvents.subscribe( (event) => { // hide miniapp to return to the react-native app page Boxo.hideMiniapps(); //payment data const appId = event.app_id; const paymentEvent = event.payment_event; const orderPaymentId = paymentEvent.order_payment_id; const amount = paymentEvent.amount; const currency = paymentEvent.currency; const extraParams = paymentEvent.extra_params; // display payment screen // after payment is completed // open hidden miniapp Boxo.openMiniapp(appId); //send payment result to miniapp const newEvent = { app_id: appId, payment_event: { ...event.payment_event, status: // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled }, }; Boxo.paymentEvents.send(newEvent); }, () => {}, ); return () => { ... paymentEventsSubscription(); }; }, []); ``` ```js theme={"system"} Boxo.addListener('payment_event', paymentData => { Boxo.hideMiniapps(); // Show payment processing screen and handle payment according to paymentData // paymentData.amount // paymentData.miniappOrderId // paymentData.currency // paymentData.orderPaymentId // Once payment is done, modify payment data and send result to mini app: paymentData.status = 'success'; // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled Boxo.sendPaymentEvent(paymentData); Boxo.openMiniapp({ paymentData.appId }); }); ``` ```js theme={"system"} Boxo.addPaymentEventListener((paymentData) => { // Show payment processing screen and handle payment according to paymentData // paymentData.amount // paymentData.miniappOrderId // paymentData.currency // paymentData.orderPaymentId // Once payment is done, modify payment data and send result to mini app: Boxo.hideMiniapps(); paymentData.status = "success"; // change the payment status. "failed" in case payment failed, "cancelled" in case payment cancelled Boxo.sendPaymentEvent(paymentData); Boxo.openMiniapp({ appId: paymentData.appId }) }); ``` # Boxo SDK Source: https://boxo.mintlify.app/host-apps/BoxoSDK ## iOS SDK Your project must target iOS 10 or later. Swift projects should use Swift 4.2 or later, and CocoaPods 1.8.1 or later is required. Add a package by selecting File → Add Packages… in Xcode's menu bar. Search for the BoxoSDK using the repo's URL: ```sh theme={"system"} https://github.com/Appboxo/boxo-ios-spm.git ``` Next, set the **Dependency Rule** to be Up to Next Major Version. Then, select **Add Package**. Using [CocoaPods](https://guides.cocoapods.org/using/getting-started.html#getting-started) to create a Podfile if you don't already have one. ```sh theme={"system"} cd your-project-directory pod init ``` Add the Boxo pod to your Podfile ```sh theme={"system"} pod 'BoxoSDK' ``` Install the pods, then open your .xcworkspace file to see the project in Xcode: ```sh theme={"system"} pod install open your-project.xcworkspace ``` Import Boxo SDK in your ViewController: ```swift theme={"system"} import BoxoSDK ``` Initialize Boxo in your app by configuring a Boxo shared instance. Remember to replace `client_id` field with your `client_id`. ```swift theme={"system"} let config = Config(clientId: "client_id") Boxo.shared.setConfig(config: config) ``` To launch the miniapp, you will need a UIViewController: #### UIKit To open miniapp write this code in your UIViewController: ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") miniapp.open(viewController: self) ``` #### SwiftUI If you are using SwiftUI, you need to access the current UIViewController. There are many ways to obtain a UIViewController. Here is one of them: ```swift theme={"system"} struct ViewControllerFinder: UIViewControllerRepresentable { var onViewControllerFound: (UIViewController) -> Void func makeUIViewController(context: Context) -> UIViewController { let viewController = UIViewController() DispatchQueue.main.async { self.onViewControllerFound(viewController) } return viewController } func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} } ... struct ContentView: View { @State private var currentViewController: UIViewController? var body: some View { ViewControllerFinder { viewController in currentViewController = viewController } Button(action: { guard let currentViewController = currentViewController else { return } let miniapp = Boxo.shared.getMiniapp(appId: "app_id") miniapp.open(viewController: currentViewController) }) { Text("Open miniapp") } } } ``` Configure BoxoSDK with these settings to customize behavior, language, and UI elements. #### Language Configuration Use it to provide language to miniapp. Default: 'en' ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.language = "en" Boxo.shared.setConfig(config: config) ``` #### Consent Management ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.setUserId(id: "HOST_APP_USER_ID") //will be used for the consent screen Boxo.shared.setConfig(config: config) ``` #### Miniapp Menu Customization ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.permissionsPage = false // Hide "Settings" config.showClearCache = false // Hide "Clear Cache" config.showAboutPage = false // Show "About" Boxo.shared.setConfig(config: config) ``` | **Parameter** | **Description** | **Default** | | :---------------- | :---------------------- | :---------- | | `permissionsPage` | Setting menu item | `true` | | `showClearCache` | Clear Cache menu item | `true` | | `showAboutPage` | About Miniapp menu item | `true` | #### Sandbox Mode Configuration Control which miniapps are available in your development environment using the sandbox mode flag: ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.sandboxMode = true Boxo.shared.setConfig(config: config) ``` Behavior: [Retrieve Miniapp List](/host-apps/BoxoSDK#retrieve-miniapp-list) will return miniapps with the statuses listed below. | **Sandbox Mode** | **Available Miniapp** **Statuses** | **Use Case** | | :--------------- | :---------------------------------- | :------------------------------------------------------------ | | `true` | `Approved` + `InTesting` | Development environment - access to miniapps still in testing | | `false` | `Approved` only | Production environment - only fully approved miniapps | #### Theme Configuration Configure native component theming to match your app's design system or respect user preferences. The SDK provides comprehensive theme support for: * Splash screens * Native UI components * System dialogs and alerts **Theme Options**: | **Option** | **Description** | | :--------- | :--------------------------------- | | `SYSTEM` | Automatically matches device theme | | `LIGHT` | Forces light theme | | `DARK` | Forces dark theme | Control theme behavior at both global and per-miniapp levels for maximum flexibility. **Global Theme (Affects all miniapps)** ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.theme = .System Boxo.shared.setConfig(config: config) ``` **Per-Miniapp Theme Override** ```swift theme={"system"} // Override theme for specific miniapp miniapp.setConfig(config: MiniappConfig(theme: .Dark)) ``` Handle authentication between your host app and miniapps: ```swift theme={"system"} miniapp.delegate = self ... extension ViewController : MiniappDelegate { func onAuth(miniapp: Miniapp, requiredFields: [String]) { // requiredFields - list of user data fields requested by the miniapp, // e.g. ["email", "phone"]. Empty if the miniapp doesn't require any. // 1. Fetch auth code from your backend let authCode = fetchAuthCodeFromBackend(requiredFields) // 2. Provide code to Miniapp miniapp.setAuthCode(authCode: authCode) } } ``` If you don't need `requiredFields`, the shorter overload is still available: ```swift theme={"system"} miniapp.delegate = self ... extension ViewController : MiniappDelegate { func onAuth(miniapp: Miniapp) { miniapp.setAuthCode(authCode: fetchAuthCodeFromBackend()) } } ``` The `requiredFields` parameter is available starting from iOS SDK `1.29.0`. When users log out of your host app, you must completely clear all miniapp session data ```swift theme={"system"} Boxo.shared.logout() ``` To listen for any URL change events: ```swift theme={"system"} miniapp.delegate = self ... extension ViewController: MiniappDelegate { func didChangeUrlEvent(miniapp: Miniapp, url: URL) { // Listen for search URL if url.path.components(separatedBy: "/").contains("search") { print("Search url: \(url)") } } } ``` Append additional query parameters to miniapp's initial URL for passing contextual data. This enables: * User-specific data injection * Campaign tracking * Contextual deep linking * A/B testing configuration ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") let miniappConfig = MiniappConfig() miniappConfig.setExtraParams(extraParams: ["user_id" : "u_12345", "campaign" : "summer_sale"]) miniapp.setConfig(config: miniappConfig) ``` Parameters will be automatically URL-encoded and appended as query parameters: ``` https://miniapp.example.com?user_id=u_12345&campaign=summer_sale ``` Establish two-way communication between your hostapp and miniapps using custom events. This system enables: * Real-time data exchange * User interaction tracking * Miniapp to host app callbacks * Dynamic content updates ```swift theme={"system"} miniapp.delegate = self ... func didReceiveCustomEvent(miniapp: Miniapp, customEvent: CustomEvent) { customEvent.payload = [ "status" : "success", "code" : 200 ] // Send response back to miniapp miniapp.sendCustomEvent(customEvent: customEvent) } ``` You can extend the miniapp’s native menu by adding your own custom action item by defining `.setCustomActionMenuItemImage` ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") let miniappConfig = MiniappConfig() miniappConfig.setCustomActionMenuItemImage(image: UIImage(named: "ic_custom_action_button")) miniapp.setConfig(config: miniappConfig) miniapp.delegate = self ... extension ViewController : MiniappDelegate { func didSelectCustomActionMenuItemEvent(miniapp: Miniapp) { // do something } } ``` **Control Visibility:** ``` // Hide the item miniapp.hideCustomActionMenuItem() // Show when needed miniapp.showCustomActionMenuItem() ``` Fetch the complete catalog of available miniapps with detailed metadata. This operation returns: * Basic miniapp information (id, name, description) * Logo * Category ```swift theme={"system"} Boxo.shared.getMiniapps { miniapps, error in miniapps.forEach { data in print(data.appId) print(data.name) print(data.longDescription) print(data.logo) print(data.category) } } ``` When a miniapp is launched, Boxo displays a splash screen while the content is loading. You can customize the splash screen background color and the loading progress indicator for both **light** and **dark** themes. ### Background Colors Use the `splashBackgroundColors` property to configure splash background colors: ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.splashBackgroundColors = SplashBackgroundColors(light: UIColor.white, dark: UIColor.black) Boxo.shared.setConfig(config: config) ``` ### Progress Bar Colors Use the `progressBarColors` property to configure progress bar colors: ```swift theme={"system"} let config = Config(clientId: "CLIENT_ID") config.progressBarColors = ProgressBarColors(lightIndicator: UIColor.red, lightTrack: UIColor.yellow, darkIndicator: UIColor.green, darkTrack: UIColor.orange) Boxo.shared.setConfig(config: config) ``` ### Splash Behavior By default, the splash screen is shown automatically and hides when approximately 50% of the web content has loaded. You can control this behavior using `MiniappConfig`. For example, to disable the splash screen entirely: ```swift theme={"system"} let miniapp = Boxo.shared.getMiniapp(appId: "app_id") let miniappConfig = MiniappConfig() miniappConfig.enableSplash(isSplashEnabled: false) miniapp.setConfig(config: miniappConfig) miniapp.open(viewController: self) ``` Customize the animation effects to enhance the user experience by setting the appropriate page transition animation when opening a miniapp. You can choose from the following page animations: * `LEFT_TO_RIGHT` - The miniapp slides in from the left side of the screen to the right. * `RIGHT_TO_LEFT` - The miniapp slides in from the right side of the screen to the left. * `BOTTOM_TO_TOP`- The miniapp slides in from the bottom of the screen to the top. * `TOP_TO_BOTTOM` - The miniapp slides in from the top of the screen to the bottom. * `FADE_IN` - The miniapp fades in gradually from completely transparent to opaque. The `BOTTOM_TO_TOP` animation is the default page transition effect. You can easily change the animation to any of the other available options based on the user experience you want to provide. ```swift theme={"system"} let config = MiniappConfig() config.pageAnimation = PageAnimation.RIGHT_TO_LEFT let miniapp = Boxo.shared.getMiniapp(appId: "app_id") miniapp.setConfig(config: config) miniapp.open(viewController: self) ``` Miniapp lifecycle events allow you to monitor key activities, such as `onLaunch`, `onResume`, `onPause`, `onClose`, `onError`, and `onUserInteraction`. These events help track the miniapp's behavior throughout its usage lifecycle. ```swift theme={"system"} miniapp.delegate = self ... extension ViewController: MiniappDelegate { func onLaunch(miniapp: Miniapp) { print("onLaunchMiniapp: \(miniapp.appId)") } func onResume(miniapp: Miniapp) { print("onResumeMiniapp: \(miniapp.appId)") } func onPause(miniapp: Miniapp) { print("onPauseMiniapp: \(miniapp.appId)") } func onClose(miniapp: Miniapp) { print("onCloseMiniapp: \(miniapp.appId)") } func onError(miniapp: Miniapp, message: String) { print("onErrorMiniapp: \(miniapp.appId) message: \(message)") } func onUserInteraction(miniapp: Miniapp) { print("onUserInteractionMiniapp: \(miniapp.appId)") } } ``` ## Android SDK Please see our [sample Android app](https://github.com/Appboxo/sample-android-hostapp) to learn more. Your project must target at least Android 5.0 (API level 21) or higher. The host Activity must extend `FragmentActivity` (for example, `AppCompatActivity`). A plain `Activity` without fragment support is not supported. Latest version: ![Maven Central Version](https://img.shields.io/maven-central/v/io.boxo.sdk/boxo-android) To install Boxo SDK, add `io.boxo.sdk:boxo-android` to the `dependencies` block of your [app/build.gradle](https://developer.android.com/studio/build/dependencies) file: ```kotlin app/build.gradle.kts theme={"system"} ... dependencies { implementation("io.boxo.sdk:boxo-android:1.x.x") } ``` 1. Add to your existing `Application` class or create a new one if you don't have an `Application` class yet. ```kotlin MyApplication.kt theme={"system"} import android.app.Application import io.boxo.sdk.Boxo import io.boxo.sdk.Config class MyApplication : Application() { override fun onCreate() { super.onCreate() Boxo.init(this) .setConfig( Config.Builder() .setClientId("client_id") .build() ) } } ``` 2. Then register it in AndroidManifest.xml: ```AndroidManifest.xml theme={"system"} ``` 3. Open miniapp ```kotlin theme={"system"} val miniapp = Boxo.getMiniapp(appId) miniapp.open() ``` ```kotlin MainActivity.kt [expandable] theme={"system"} package io.boxo.launchminiapp import android.os.Bundle import androidx.fragment.app.FragmentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import io.boxo.launchminiapp.ui.theme.LaunchminiappTheme import io.boxo.sdk.Boxo class MainActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { LaunchminiappTheme { WelcomeScreen( onOpenMiniappClick = { Boxo.getMiniapp("appId").open() } ) } } } } @Composable fun WelcomeScreen( onOpenMiniappClick: () -> Unit, modifier: Modifier = Modifier ) { Column( modifier = modifier .fillMaxSize() .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "Welcome", style = typography.headlineMedium, modifier = Modifier.padding(bottom = 16.dp) ) Spacer(modifier = modifier.height(64.dp)) Button( onClick = onOpenMiniappClick, modifier = Modifier .fillMaxWidth() .height(52.dp) ) { Text("Open Miniapp") } } } @Preview(showBackground = true) @Composable fun WelcomeScreenPreview() { LaunchminiappTheme { WelcomeScreen( onOpenMiniappClick = {} ) } } ``` Configure BoxoSDK with these settings to customize behavior, language, and UI elements. #### Language Configuration Use it to provide language to miniapp. Default: 'en' ``` Boxo.init(this) .setConfig( Config.Builder() .setLanguage("en") .build() ) ``` #### System Behavior ``` Boxo.setConfig( Config.Builder() .debug(BuildConfig.DEBUG) .build() ) ``` | **Parameter** | **Type** | **Description** | **Default** | | :------------ | :------- | :------------------------------------------ | :---------- | | `debug` | Boolean | Enables WebView debugging (Chrome DevTools) | `false` | #### Miniapp Menu Customization ``` Boxo.setConfig( Config.Builder() .permissionsPage(false) // Hide "Settings" .showClearCache(false) // Hide "Clear Cache" .showAboutPage(true) // Show "About" .build() ) ``` | **Parameter** | **Description** | **Default** | | :---------------- | :---------------------- | :---------- | | `permissionsPage` | Setting menu item | `true` | | `showClearCache` | Clear Cache menu item | `true` | | `showAboutPage` | About Miniapp menu item | `true` | #### Sandbox Mode Configuration Control which miniapps are available in your development environment using the sandbox mode flag: ```kotlin theme={"system"} Boxo.setConfig( Config.Builder() .sandboxMode(true) // Enable sandbox mode .build() ) ``` Behavior: [Retrieve Miniapp List](/host-apps/BoxoSDK#retrieve-miniapp-list) will return miniapps with the statuses listed below. | **Sandbox Mode** | **Available Miniapp** **Statuses** | **Use Case** | | :--------------- | :---------------------------------- | :------------------------------------------------------------ | | `true` | `Approved` + `InTesting` | Development environment - access to miniapps still in testing | | `false` | `Approved` only | Production environment - only fully approved miniapps | #### Theme Configuration Configure native component theming to match your app's design system or respect user preferences. The SDK provides comprehensive theme support for: * Splash screens * Native UI components * System dialogs and alerts **Theme Options**: | **Option** | **Description** | | :--------- | :--------------------------------- | | `SYSTEM` | Automatically matches device theme | | `LIGHT` | Forces light theme | | `DARK` | Forces dark theme | Control theme behavior at both global and per-miniapp levels for maximum flexibility. **Global Theme (Affects all miniapps)** ```kotlin theme={"system"} Boxo.setConfig(Config.Builder() ... .setTheme(Config.Theme.SYSTEM) // DEFAULT: Follows system setting .build()) ``` **Per-Miniapp Theme Override** ```kotlin theme={"system"} // Override theme for specific miniapp Boxo.getMiniapp(appId) .setConfig(MiniappConfig.Builder() .setTheme(Config.Theme.LIGHT) // Overrides global theme .build()) .open() ``` Handle authentication between your host app and miniapps: ```kotlin theme={"system"} miniapp.setAuthListener { _, miniapp, requiredFields -> // requiredFields - list of user data fields requested by the miniapp, // e.g. ["email", "phone"]. Empty if the miniapp doesn't require any. // 1. Fetch auth code from your backend val authCode = fetchAuthCodeFromBackend(requiredFields) // 2. Provide code to Miniapp miniapp.setAuthCode(authCode) } ``` If you don't need `requiredFields`, the shorter overload is still available: ```kotlin theme={"system"} miniapp.setAuthListener { _, miniapp -> miniapp.setAuthCode(fetchAuthCodeFromBackend()) } ``` The `requiredFields` parameter is available starting from Android SDK `1.43.0`. When users log out of your host app, you must completely clear all miniapp session data ```kotlin theme={"system"} Boxo.logout() ``` To listen for any URL change events use .setUrlChangeListener: ```kotlin theme={"system"} Boxo.getMiniapp(appId) .setUrlChangeListener { _, miniapp, uri -> Log.e("URL Path", uri.path) uri.queryParameterNames.forEach { Log.e("URL params", "$it = ${uri.getQueryParameter(it)}") } } .open() ``` Append additional query parameters to miniapp's initial URL for passing contextual data. This enables: * User-specific data injection * Campaign tracking * Contextual deep linking * A/B testing configuration **Basic Implementation** ```kotlin theme={"system"} Boxo.getMiniapp(appId) .setConfig( MiniappConfig.Builder() .setExtraUrlParams( mapOf( "user_id" to "u_12345", "campaign" to "summer_sale" ) ) .build() ) .open() ``` Parameters will be automatically URL-encoded and appended as query parameters: ``` https://miniapp.example.com?user_id=u_12345&campaign=summer_sale ``` Establish two-way communication between your hostapp and miniapps using custom events. This system enables: * Real-time data exchange * User interaction tracking * Miniapp to host app callbacks * Dynamic content updates ```kotlin theme={"system"} miniapp.setCustomEventListener { _, miniapp, event -> when (event.name) { "userAction" -> handleUserAction(event.payload) "requestData" -> sendResponseData(miniapp, event) else -> Log.w("CustomEvent", "Unhandled event: ${event.name}") } } // Send response back to miniapp private fun sendResponseData(miniapp: Miniapp, event: CustomEvent) { event.payload = mapOf( "status" to "success", "code" to 200 ) miniapp.sendEvent(event) } ``` You can extend the miniapp's native menu by adding your own custom action item. This is achieved through two simple steps: 1. **Define the Menu Item**\ Use `.setCustomActionMenuItem()` to specify your custom button's appearance 2. **Handle User Interactions**\ Implement `.setCustomActionMenuItemClickListener()` to respond when users tap your button ```kotlin theme={"system"} Boxo.getMiniapp(appId) .setConfig( MiniappConfig.Builder() .setCustomActionMenuItem(R.drawable.ic_custom_menu) .build() ) .setCustomActionMenuItemClickListener { _, miniapp -> // do something } .open() ``` **Control Visibility:** ``` // Hide the item miniapp.hideCustomActionMenuItem() // Show when needed miniapp.showCustomActionMenuItem() ``` Fetch the complete catalog of available miniapps with detailed metadata. This asynchronous operation returns: * Basic miniapp information (id, name, description) * Logo * Category ```kotlin theme={"system"} Boxo.getMiniapps(object: MiniappListCallback{ override fun onFailure(e: Exception) { Log.e("MiniappList", "Failed to load miniapps") } override fun onSuccess(miniapps: List) { miniapps.forEach { data-> print(data.appId) print(data.name) print(data.description) print(data.logo) print(data.category) } } }) ``` When a miniapp is launched, Boxo displays a splash screen while the content is loading. You can customize the splash screen background color and the loading progress indicator for both **light** and **dark** themes. ### Background Colors Use the `setSplashBackgroundColors` method in `Config.Builder` to configure splash background colors: ```kotlin theme={"system"} Boxo.init(this) .setConfig( Config.Builder() .setSplashBackgroundColors( light = "#6A22C9".toColorInt(), dark = "#C495FF".toColorInt() ) .build() ) ``` ### Progress Bar Colors Use the `setProgressBarColors` method in `Config.Builder` to configure progress bar colors: ```kotlin theme={"system"} Boxo.init(this) .setConfig( Config.Builder() .setProgressBarColors( lightIndicator = "#000000".toColorInt(), lightTrack = "#DAD5D5".toColorInt(), darkIndicator = "#006DD1".toColorInt(), darkTrack = "#FFFFFF".toColorInt() ) .build() ) ``` ### Splash Behavior By default, the splash screen is shown automatically and hides when approximately 50% of the web content has loaded. You can control this behavior using `MiniappConfig`. For example, to disable the splash screen entirely: ```kotlin theme={"system"} Boxo.getMiniapp(appId) .setConfig( MiniappConfig.Builder() .enableSplash(false) // Disable splash screen .build() ) .open() ``` Customize the animation effects to enhance the user experience by setting the appropriate page transition animation when opening a miniapp. You can choose from the following page animations: * `LEFT_TO_RIGHT` - The miniapp slides in from the left side of the screen to the right. * `RIGHT_TO_LEFT` - The miniapp slides in from the right side of the screen to the left. * `BOTTOM_TO_TOP`- The miniapp slides in from the bottom of the screen to the top. * `TOP_TO_BOTTOM` - The miniapp slides in from the top of the screen to the bottom. * `FADE_IN` - The miniapp fades in gradually from completely transparent to opaque. The `BOTTOM_TO_TOP` animation is the default page transition effect. You can easily change the animation to any of the other available options based on the user experience you want to provide. ``` Boxo.getMiniapp(appId) .setConfig( MiniappConfig.Builder() ... // Set the page animation to slide from right to left .pageAnimation(PageAnimation.RIGHT_TO_LEFT) .build() ) .open() ``` Track key moments in a miniapp's execution by implementing the `LifecycleListener`. The callbacks `onLaunch`, `onResume`, `onPause`, `onClose`, `onError`, and `onUserInteraction` let you monitor the miniapp lifecycle and user touches. ```kotlin theme={"system"} miniapp.setLifecycleListener(object : Miniapp.LifecycleListener { override fun onLaunch(miniapp: Miniapp) { // Triggers when miniapp begins launching via miniapp.open() // Ideal for analytics tracking and initial setup } override fun onResume(miniapp: Miniapp) { // Called when miniapp returns to foreground // Use to resume paused operations } override fun onPause(miniapp: Miniapp) { // Called when miniapp loses foreground focus // Pause ongoing operations } override fun onClose(miniapp: Miniapp) { // Triggers when: // - User taps close button // - Miniapp activity is destroyed // Clean up resources and finalize analytics } override fun onError(miniapp: Miniapp, message: String) { // Called when miniapp fails to launch due to internet connection issues } override fun onUserInteraction(miniapp: Miniapp) { // Called whenever a touch event is dispatched to the miniapp page // Useful for custom idle timeouts } }) ``` To protect intellectual property, deter reverse engineering, and enhance code security ```js theme={"system"} -keepclassmembers class io.boxo.js.jsInterfaces.BoxoJsInterface{ public *; } ``` ## Flutter A [Flutter plugin](https://pub.dev/packages/appboxo_sdk) to integrate Boxo for iOS and Android. Please see our [sample Flutter app](https://github.com/Appboxo/sample-flutter-app) to learn more. ![Pub Version](https://img.shields.io/pub/v/appboxo_sdk) Run this command: With Flutter: ```bash theme={"system"} flutter pub add appboxo_sdk ``` This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get): dependencies: appboxo\_sdk: ^0.8.0 Add this line to android/gradle.properties ``` android.enableJetifier=true ``` ``` import 'package:appboxo_sdk/boxo.dart'; ``` ``` Boxo.setConfig( clientId: '[client_id]'); ``` ``` Boxo.openMiniapp( appId ); ``` ```dart theme={"system"} import 'package:appboxo_sdk/boxo.dart'; Boxo.setConfig( clientId: '[client_id]', // your Boxo client_id userId: '[hostapp_user_id]',// will be used for the consent screen language: 'en', // use it to provide language to miniapp. by default 'en' sandboxMode: false, // sandbox mode. By default 'false' theme: 'dark', // (optional) miniapp theme "dark" | "light" (by default is system theme), isDebug: true, // by default 'false', enables webview debugging showClearCache: true, // use it to hide "Clear cache" from Miniapp menu, by default 'true' showPermissionsPage: true, // use it to hide "Settings" from Miniapp menu, by default 'true' showAboutPage: true, // show/hide "About page" on Miniapp menu, by default 'true' splashScreenOptions: { // (optional) to customize the splash screen background and the loading progress indicator 'light_progress_indicator': '#000000', 'light_progress_track': '#FFFFFF', 'light_background': '#FFFFF', 'dark_progress_indicator': '#FFFFFF', 'dark_progress_track': '#000000', 'dark_background': '#000000' } ); Boxo.openMiniapp( "[miniapp_id]", // your miniapp id data: {'key': 'value'}, // (optional) data as Map that is sent to miniapp theme: 'dark', // (optional) miniapp theme "dark" | "light" (by default is system theme) enableSplash: false // (optional) to skip splash screen. if enabled, the splash screen will be hidden when 50% of web content is loaded. Otherwise, when the web page starts loading. By default is enabled. ); Boxo.hideMiniapps(); //use it to close all miniapp screens Boxo.logout(); //On logout from your app, call it to clear all miniapps data. ``` When a miniapp is launched, Boxo displays a splash screen while the content is loading. You can customize the splash screen background color and the loading progress indicator for both **light** and **dark** themes. ### Background and progress colors Pass `splashScreenOptions` to `Boxo.setConfig`. Keys use snake case and hex color strings: | Key | Description | | :------------------------- | :------------------------------------ | | `light_background` | Splash background in light appearance | | `dark_background` | Splash background in dark appearance | | `light_progress_indicator` | Progress indicator color (light) | | `light_progress_track` | Progress track color (light) | | `dark_progress_indicator` | Progress indicator color (dark) | | `dark_progress_track` | Progress track color (dark) | ```dart theme={"system"} Boxo.setConfig( clientId: '[client_id]', splashScreenOptions: { 'light_background': '#FFFFFF', 'dark_background': '#000000', 'light_progress_indicator': '#000000', 'light_progress_track': '#FFFFFF', 'dark_progress_indicator': '#FFFFFF', 'dark_progress_track': '#000000', }, ); ``` ### Splash behavior By default, the splash screen is shown automatically and hides when approximately 50% of the web content has loaded. Pass `enableSplash` to `Boxo.openMiniapp` to control it for a single launch (for example, to turn it off): ```dart theme={"system"} Boxo.openMiniapp( '[miniapp_id]', enableSplash: false, ); ``` Customize the animation effects when opening a miniapp by passing `pageAnimation` to `Boxo.openMiniapp`. You can choose from the following page animations: * `LEFT_TO_RIGHT` - The miniapp slides in from the left side of the screen to the right. * `RIGHT_TO_LEFT` - The miniapp slides in from the right side of the screen to the left. * `BOTTOM_TO_TOP` - The miniapp slides in from the bottom of the screen to the top. * `TOP_TO_BOTTOM` - The miniapp slides in from the top of the screen to the bottom. * `FADE_IN` - The miniapp fades in gradually from completely transparent to opaque. The `BOTTOM_TO_TOP` animation is the default page transition effect. ```dart theme={"system"} Boxo.openMiniapp( '[miniapp_id]', pageAnimation: 'RIGHT_TO_LEFT', ); ``` sandboxMode: it should open miniapps in "Approved" and "InTesting" statuses [List of miniapps](/host-apps/BoxoSDK#get-list-of-miniapps-3) returns: * when true, miniapps in "Approved" and "InTesting" statuses * when false, miniapps only in "Approved" status ```dart theme={"system"} Boxo.miniapps().listen((result) { result.miniapps?.forEach((data) { print(data.appId); print(data.name); print(data.description); print(data.logo); print(data.category); }); print('error - ${result.error}'); }); Boxo.getMiniapps(); ``` ```dart theme={"system"} import 'package:flutter/material.dart'; import 'package:appboxo_sdk/boxo.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { Future Function() subscription; @override void dispose() { subscription(); super.dispose(); } @override void initState() { super.initState(); subscription = Boxo.lifecycleHooksListener( onAuth: (appId) { // called when authorization flow starts //sample http.get(Uri.parse('get_auth_code_url')) .then((response) { if (response.statusCode >= 400) { print('Error fetching auth code: ${response.body}'); Boxo.setAuthCode(appId, ""); } else { Boxo.setAuthCode(appId, json.decode(response.body)["auth_code"]); } }); }, onLaunch: (appId) { print(appId); print('onLaunch'); }, onResume: (appId) { print(appId); print('onResume'); }, onPause: (appId) { print(appId); print('onPause'); }, onClose: (appId) { print(appId); print('onClose'); }, onError: (appId, error) { print(appId); print(error); print('onError'); }, onUserInteraction: (appId) { print(appId); print('onUserInteraction'); }, ); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: const Text('Boxo SDK Test'), ), body: Center( child: MaterialButton( onPressed: () { Boxo.openMiniapp("[miniapp_id]"); //launch miniapp by id }, padding: const EdgeInsets.all(16), color: Colors.blue, child: const Text( 'Run miniapp', style: const TextStyle( color: Colors.white, fontSize: 16, ), ), ), ), ), ); } } ``` ## React Native A react native wrapper over Boxo SDK for iOS and Android. ``` yarn add @appboxo/react-native-sdk ``` or ``` npm install @appboxo/react-native-sdk ``` Please make sure the "@appboxo/react-native-sdk" dependency is linked, if not please run: ``` react-native link @appboxo/react-native-sdk ``` Add this line to android/gradle.properties ``` android.enableJetifier=true ``` Next for iOS: ``` cd ios && pod install ``` ``` import Boxo from '@appboxo/react-native-sdk'; ``` ``` Boxo.setConfig( clientId ); ``` ``` Boxo.openMiniapp( appId ); ``` ```clike theme={"system"} import React from 'react'; import Boxo from '@appboxo/react-native-sdk'; import { StyleSheet, View, Button } from 'react-native'; export default function App() { React.useEffect(() => { Boxo.setConfig( '[client_id]', { // your Boxo client_id userId: [hostapp_user_id], // will be used for the consent screen language: 'en', // to provide language to miniapp. by default 'en' sandboxMode: false, // sandbox mode. By default 'false' theme: 'light', // (optional) miniapp theme "dark" | "light" (by default is "system") isDebug: true, // by default 'false', enables webview debugging showClearCache: true, // use it to hide "Clear cache" from Miniapp menu, by default 'true' showPermissionsPage: true, // use it to hide "Settings" from Miniapp menu, by default 'true' showAboutPage: true, // show/hide "About page" on Miniapp menu, by default 'true' splashScreenOptions: { // (optional) to customize the splash screen background and the loading progress indicator lightProgressIndicator: "#000000", lightProgressTrack: "#FFFFFF", darkProgressIndicator: "#FFFFFF", darkProgressTrack: "#000000", lightBackground:"#FFFFFF", darkBackground:"#000000" } } ); }, []) const handleOpenMiniapp = () => { const options = { data: {'key': 'value'}, // (optional) data as {[key: string]: any} that is passed to miniapp in `.getInitData` call theme: 'dark', // (optional) miniapp theme "dark" | "light" | "system" (by default is value of "theme" argument in setConfig function) extraUrlParams: {param: 'test'}, // (optional) extra query params to append to miniapp URL (like: http://miniapp-url.com/?param=test) pageAnimation: 'RIGHT_TO_LEFT', // (optional) launch transition, see Page Animation Configuration below } Boxo.openMiniapp( '[miniapp_id]', // miniapp ID to be launched options // (optional) options ); } return ( ``` ```javascript js/example.js [expandable] theme={"system"} import { Boxo } from 'capacitor-boxo-sdk'; const clientId = ''; const appId = ''; Boxo.setConfig({ clientId: clientId }); window.openMiniapp = () => { Boxo.openMiniapp({ appId: appId}); }; ``` ### Set Config ```typescript theme={"system"} setConfig(options: ConfigOptions) => Promise ``` **Config Options** | Prop | Type | Description | | ----------------------------- | ------------------------------------------ | ------------------------------------------------------------------------ | | clientId | string | your client id from dashboard | | userId | string | (optional) hostapp userId, will be used for the Consent Management | | language | string | language value will be passed to the miniapp | | sandboxMode | boolean | switch to sandbox mode | | theme | 'light' \| 'dark' \| 'system' | theme for splash screen and other native components used inside miniapp. | | isDebug | boolean | enables webview debugging | | showPermissionsPage | boolean | use it to hide "Settings" from Miniapp menu | | showClearCache | boolean | use it to hide "Clear cache" from Miniapp menu | | showAboutPage | boolean | use it to hide "About Page" from Miniapp menu | | miniappSettingsExpirationTime | number | use it to change miniapp settings cache time in sec. Default: 60 sec | | splashScreenOptions | SplashScreenOptions | (optional) setup splash screen configs | **SplashScreenOptions** | Prop | Type | | ---------------------- | ------------------- | | lightBackground | string | | darkBackground | string | | lightProgressIndicator | string | | lightProgressTrack | string | | darkProgressIndicator | string | | darkProgressTrack | string | When a miniapp is launched, Boxo displays a splash screen while the content is loading. You can customize the splash screen background color and the loading progress indicator for both **light** and **dark** themes. ### Background and progress colors Call `Boxo.setConfig` with `splashScreenOptions` (hex strings). The same fields are listed in the Set Config section above. ```typescript theme={"system"} await Boxo.setConfig({ clientId: clientId, splashScreenOptions: { lightBackground: '#FFFFFF', darkBackground: '#000000', lightProgressIndicator: '#000000', lightProgressTrack: '#FFFFFF', darkProgressIndicator: '#FFFFFF', darkProgressTrack: '#000000', }, }); ``` ### Splash behavior By default, the splash screen is shown automatically and hides when approximately 50% of the web content has loaded. Pass `enableSplash` in `openMiniapp` to control splash for that launch (`false` disables it): ```typescript theme={"system"} await Boxo.openMiniapp({ appId: appId, enableSplash: false, }); ``` Customize the animation effects when opening a miniapp by setting `pageAnimation` in `openMiniapp` options. You can choose from the following page animations: * `LEFT_TO_RIGHT` - The miniapp slides in from the left side of the screen to the right. * `RIGHT_TO_LEFT` - The miniapp slides in from the right side of the screen to the left. * `BOTTOM_TO_TOP` - The miniapp slides in from the bottom of the screen to the top. * `TOP_TO_BOTTOM` - The miniapp slides in from the top of the screen to the bottom. * `FADE_IN` - The miniapp fades in gradually from completely transparent to opaque. The `BOTTOM_TO_TOP` animation is the default page transition effect. ```typescript theme={"system"} await Boxo.openMiniapp({ appId: appId, pageAnimation: 'RIGHT_TO_LEFT', }); ``` #### Open ```typescript theme={"system"} openMiniapp(options: OpenMiniappOptions) => Promise ``` Open miniapp with options **OpenMiniappOptions** | Prop | Type | Description | | -------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | appId | string | miniapp id | | data | object | (optional) data as Map that is sent to miniapp | | theme | 'light' \| 'dark' \| 'system' | (optional) miniapp theme "dark" \| "light" (by default is system theme) | | extraUrlParams | object | (optional) extra query params to append to miniapp URL (like: [http://miniapp-url.com/?param=test](http://miniapp-url.com/?param=test)) | | urlSuffix | string | (optional) suffix to append to miniapp URL (like: [http://miniapp-url.com/?param=test](http://miniapp-url.com/?param=test)) | | colors | ColorOptions | (optional) provide colors to miniapp if miniapp supports | | enableSplash | boolean | (optional) use to skip miniapp splash screen | | saveState | boolean | (optional) use to save state on close miniapp | | pageAnimation | 'BOTTOM\_TO\_TOP' \| 'TOP\_TO\_BOTTOM' \| 'LEFT\_TO\_RIGHT' \| 'RIGHT\_TO\_LEFT' \| 'FADE\_IN' | (optional) use to change launch animation for miniapp | **ColorOptions** | Prop | Type | | -------------- | ------------------- | | primaryColor | string | | secondaryColor | string | | tertiaryColor | string | #### Close ```typescript theme={"system"} closeMiniapp(options: { appId: string; }) => Promise ``` close miniapp by appId #### Hide ```typescript theme={"system"} hideMiniapps() => Promise ``` Miniapp opens on a native screen. To show payment processing page need to hide miniapp screen. Handle authentication between your host app and miniapps: ```typescript theme={"system"} setAuthCode(options: { appId: string; authCode: string; }) => Promise ``` When users log out of your host app, you must completely clear all miniapp session data ```typescript theme={"system"} logout() => Promise ``` ```typescript theme={"system"} getMiniapps() => Promise ``` Get list of miniapps **MiniappListResult** | Prop | Type | | -------- | --------------------------- | | miniapps | \[MiniappData] | | error | string | **MiniappData** | Prop | Type | | ----------- | ------------------- | | appId | string | | name | string | | category | string | | description | string | | logo | string | ```typescript theme={"system"} addListener(eventName: 'custom_event', listenerFunc: (customEvent: CustomEvent) => void) => Promise ``` When host app user logs out, it is highly important to clear all miniapp storage data. | Param | Type | | ------------ | -------------------------------------------------------------------------- | | eventName | 'custom\_event' | | listenerFunc | (customEvent: CustomEvent) => void | ```typescript theme={"system"} sendCustomEvent(customEvent: CustomEvent) => Promise ``` send custom event data to miniapp | Prop | Type | | --------- | ------------------- | | appId | string | | requestId | number | | type | string | | errorType | string | | payload | object | ```typescript theme={"system"} addListener(eventName: 'payment_event', listenerFunc: (paymentEvent: PaymentEvent) => void) => Promise ``` | Param | Type | | ------------ | ----------------------------------------------------------------------------- | | eventName | 'payment\_event' | | listenerFunc | (paymentEvent: PaymentEvent) => void | ```typescript theme={"system"} sendPaymentEvent(paymentEvent: PaymentEvent) => Promise ``` send payment data to miniapp | Prop | Type | | -------------- | ------------------- | | appId | string | | orderPaymentId | string | | miniappOrderId | string | | amount | number | | currency | string | | status | string | | hostappOrderId | string | | extraParams | object | ```typescript theme={"system"} addListener(eventName: 'miniapp_lifecycle', listenerFunc: (lifecycle: LifecycleEvent) => void) => Promise ``` | Param | Type | | ------------ | ------------------------------------------------------------------------------ | | eventName | 'miniapp\_lifecycle' | | listenerFunc | (lifecycle: LifecycleEvent) => void | **LifecycleEvent** | Prop | Type | | --------- | ------------------- | | appId | string | | lifecycle | string | | error | string | onLaunch - Called when the miniapp will launch with Boxo.open(...) onResume - Called when the miniapp will start interacting with the user onPause - Called when the miniapp loses foreground state onClose - Called when clicked close button in miniapp or when destroyed miniapp page onError - Called when miniapp fails to launch due to internet connection issues onUserInteraction - Called whenever a touch event is dispatched to the miniapp page onAuth - Called when the miniapp starts login and user allows it ## Expo [Expo plugin](https://www.npmjs.com/package/@appboxo/expo-boxo-sdk) to integrate Boxo for iOS and Android. Please see our [sample Expo app](https://github.com/Appboxo/expo-boxo-sdk/tree/main/example) to learn more. ```bash theme={"system"} npm install @appboxo/expo-boxo-sdk ``` Configuration in app.json/app.config.js ```json theme={"system"} { "expo": { "plugins": [ ["@appboxo/expo-boxo-sdk"] ] } } ``` ``` import * as Boxo from 'expo-boxo-sdk'; ``` ``` Boxo.setConfig({ clientId: clientId }); ``` ``` Boxo.openMiniapp({ appId: appId }); ``` ```typescript theme={"system"} setConfig(options: ConfigOptions) ``` **ConfigOptions** | Prop | Type | Description | | ----------------------------- | ------------------------------------------ | ------------------------------------------------------------------------ | | clientId | string | your client id from dashboard | | userId | string | (optional) hostapp userId, will be used for the Consent Management | | language | string | language value will be passed to the miniapp | | sandboxMode | boolean | switch to sandbox mode | | theme | 'light' \| 'dark' \| 'system' | theme for splash screen and other native components used inside miniapp. | | isDebug | boolean | enables webview debugging | | showPermissionsPage | boolean | use it to hide "Settings" from Miniapp menu | | showClearCache | boolean | use it to hide "Clear cache" from Miniapp menu | | showAboutPage | boolean | use it to hide "About Page" from Miniapp menu | | miniappSettingsExpirationTime | number | use it to change miniapp settings cache time in sec. Default: 60 sec | | splashScreenOptions | SplashScreenOptions | (optional) setup splash screen configs | **SplashScreenOptions** | Prop | Type | | ---------------------- | ------------------- | | lightBackground | string | | darkBackground | string | | lightProgressIndicator | string | | lightProgressTrack | string | | darkProgressIndicator | string | | darkProgressTrack | string | When a miniapp is launched, Boxo displays a splash screen while the content is loading. You can customize the splash screen background color and the loading progress indicator for both **light** and **dark** themes. ### Background and progress colors Call `Boxo.setConfig` with `splashScreenOptions` (hex strings). The same fields are listed in the Set Config section above. ```typescript theme={"system"} Boxo.setConfig({ clientId: clientId, splashScreenOptions: { lightBackground: '#FFFFFF', darkBackground: '#000000', lightProgressIndicator: '#000000', lightProgressTrack: '#FFFFFF', darkProgressIndicator: '#FFFFFF', darkProgressTrack: '#000000', }, }); ``` ### Splash behavior By default, the splash screen is shown automatically and hides when approximately 50% of the web content has loaded. Pass `enableSplash` in `openMiniapp` to control splash for that launch (`false` disables it): ```typescript theme={"system"} Boxo.openMiniapp({ appId: appId, enableSplash: false, }); ``` Customize the animation effects when opening a miniapp by setting `pageAnimation` in `openMiniapp` options. You can choose from the following page animations: * `LEFT_TO_RIGHT` - The miniapp slides in from the left side of the screen to the right. * `RIGHT_TO_LEFT` - The miniapp slides in from the right side of the screen to the left. * `BOTTOM_TO_TOP` - The miniapp slides in from the bottom of the screen to the top. * `TOP_TO_BOTTOM` - The miniapp slides in from the top of the screen to the bottom. * `FADE_IN` - The miniapp fades in gradually from completely transparent to opaque. The `BOTTOM_TO_TOP` animation is the default page transition effect. ```typescript theme={"system"} Boxo.openMiniapp({ appId: appId, pageAnimation: 'RIGHT_TO_LEFT', }); ``` #### Open ```typescript theme={"system"} openMiniapp(options: MiniappOptions) ``` Open miniapp with options **MiniappOptions** | Prop | Type | Description | | -------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | appId | string | miniapp id | | data | object | (optional) data as Map that is sent to miniapp | | theme | 'light' \| 'dark' \| 'system' | (optional) miniapp theme "dark" \| "light" (by default is system theme) | | extraUrlParams | object | (optional) extra query params to append to miniapp URL (like: [http://miniapp-url.com/?param=test](http://miniapp-url.com/?param=test)) | | urlSuffix | string | (optional) suffix to append to miniapp URL (like: [http://miniapp-url.com/?param=test](http://miniapp-url.com/?param=test)) | | colors | ColorOptions | (optional) provide colors to miniapp if miniapp supports | | enableSplash | boolean | (optional) use to skip miniapp splash screen | | saveState | boolean | (optional) use to save state on close miniapp | | pageAnimation | 'BOTTOM\_TO\_TOP' \| 'TOP\_TO\_BOTTOM' \| 'LEFT\_TO\_RIGHT' \| 'RIGHT\_TO\_LEFT' \| 'FADE\_IN' | (optional) use to change launch animation for miniapp | **ColorOptions** | Prop | Type | | -------------- | ------------------- | | primaryColor | string | | secondaryColor | string | | tertiaryColor | string | #### Close ```typescript theme={"system"} closeMiniapp(appId: string) ``` close miniapp by appId #### Hide ```typescript theme={"system"} hideMiniapps() ``` Miniapp opens on a native screen. To show payment processing page need to hide miniapp screen. Handle authentication between your host app and miniapps: ```typescript theme={"system"} Boxo.addAuthListener((authEvent) => { Boxo.setAuthCode(authEvent.appId, authCode) }); ``` When users log out of your host app, you must completely clear all miniapp session data ```typescript theme={"system"} logout() ``` ```typescript theme={"system"} Boxo.addMiniappListListener((result) => { console.log(result.miniapps); }); ``` Get list of miniapps **MiniappListResult** | Prop | Type | | -------- | --------------------------- | | miniapps | \[MiniappData] | | error | string | **MiniappData** | Prop | Type | | ----------- | ------------------- | | appId | string | | name | string | | category | string | | description | string | | logo | string | ```typescript theme={"system"} Boxo.addCustomEventListener((customEvent) => { ..handle custom event Boxo.sendCustomEvent(customEvent); }); ``` Send custom event data to miniapp | Prop | Type | | --------- | ------------------- | | appId | string | | requestId | number | | type | string | | errorType | string | | payload | object | ```typescript theme={"system"} Boxo.addPaymentEventListener((paymentData) => { Boxo.hideMiniapps(); .. show payment page paymentData.status = "success"; ..confirm payment Boxo.sendPaymentEvent(paymentData); Boxo.openMiniapp({ appId: paymentData.appId }) }); ``` send payment data to miniapp | Prop | Type | | -------------- | ------------------- | | appId | string | | orderPaymentId | string | | miniappOrderId | string | | amount | number | | currency | string | | status | string | | hostappOrderId | string | | extraParams | object | ```typescript theme={"system"} Boxo.addMiniappLifecycleListener((lifecycleData) => { console.log(lifecycleData); }); ``` **LifecycleEvent** | Prop | Type | | --------- | ------------------- | | appId | string | | lifecycle | string | | error | string | onLaunch - Called when the miniapp will launch with Boxo.open(...) onResume - Called when the miniapp will start interacting with the user onPause - Called when the miniapp loses foreground state onClose - Called when clicked close button in miniapp or when destroyed miniapp page onError - Called when miniapp fails to launch due to internet connection issues onUserInteraction - Called whenever a touch event is dispatched to the miniapp page onAuth - Called when the miniapp starts login and user allows it ## Web SDK A JavaScript SDK for embedding miniapps into desktop web applications using iframe communication. Please see our [sample web app](https://github.com/Appboxo/sample-web-hostapp) to learn more. ```bash theme={"system"} npm install @appboxo/web-sdk ``` or ```bash theme={"system"} pnpm install @appboxo/web-sdk ``` ```typescript theme={"system"} import { AppboxoWebSDK } from "@appboxo/web-sdk"; const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id" }); // Mount miniapp await sdk.mount({ container: document.getElementById("miniapp") }); ``` ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: string; // Required appId: string; // Required userId?: string; // Optional, user reference identifier baseUrl?: string; // Optional, default: "https://dashboard.boxo.io/api/v1" sandboxMode?: boolean; // Optional, default: false debug?: boolean; // Optional, default: false. When true, enables all console logs for debugging locale?: string; // Optional, locale/language code (e.g., 'en', 'en-US', 'ru', 'zh-CN') theme?: 'dark' | 'light' | 'system'; // Optional, theme/color scheme preference (default: 'system') allowedOrigins?: string[]; // Optional, restrict message events to specific origins. Empty array allows all origins onGetAuthCode?: () => Promise; // Optional, for automatic auth code retrieval onGetAuthTokens?: () => Promise; // Optional, for direct auth tokens onPaymentRequest?: (params: PaymentRequest) => Promise; // Optional, for handling payment requests }); ``` #### Locale/Language Set the locale/language code to pass to the miniapp. The locale will be included in the InitData response. ```typescript theme={"system"} // Set locale during initialization const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", locale: "en-US" // or 'ru', 'zh-CN', etc. }); // Or set locale dynamically sdk.setLocale("ru"); ``` The locale is passed to the miniapp via `InitData.data.locale` on the next `AppBoxoWebAppGetInitData` request. **Important Notes:** * If you call `setLocale()` after the miniapp has already loaded, the locale will be included in the next InitData request. The miniapp may need to reload or request InitData again to receive the updated locale. * To ensure the locale is available immediately, set it during SDK initialization or before calling `mount()`. #### Debug Mode Control console logging for debugging: ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", debug: true // Enable debug mode }); ``` **About `debug` mode:** * `debug: false` (default): No console logs are output. Suitable for production. * `debug: true`: All SDK operations are logged to console. Useful for development and troubleshooting. * The `debug` option does not affect SDK functionality - it only controls console logging. #### Allowed Origins Control which origins can send messages to the SDK for security: ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", allowedOrigins: ["https://miniapp.example.com"] // Restrict to specific origins }); ``` **Important Notes:** * Empty array `[]` (default): Allows all origins (flexible for different deployment URLs) * Set specific origins: Only messages from listed origins will be accepted * `allowedOrigins` should be the miniapp's origin (where iframe loads from), NOT `window.location.origin` Handle authentication between your host app and miniapps. The SDK supports multiple authentication methods: **OAuth flow (using auth code):** ```typescript theme={"system"} // Set auth code explicitly const authCode = await fetch('/api/auth-code').then(r => r.json()); sdk.setAuthCode(authCode); ``` Or provide a callback: ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", onGetAuthCode: async () => { const res = await fetch('/api/generate-auth-code'); return (await res.json()).auth_code; } }); ``` **Direct auth flow (using tokens):** ```typescript theme={"system"} // Set tokens directly const tokens = await getTokensFromBackend(); sdk.setAuthTokens(tokens.access_token, tokens.refresh_token); ``` Or use callback: ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", onGetAuthTokens: async () => { const res = await fetch('/api/get-miniapp-tokens'); const result = await res.json(); return { token: result.access_token, refresh_token: result.refresh_token }; } }); ``` Or register an auth listener: ```typescript theme={"system"} sdk.onAuth(async () => { const response = await fetch('/api/get-miniapp-tokens'); const tokens = await response.json(); sdk.setAuthTokens(tokens.access_token, tokens.refresh_token); }); ``` The SDK will try these in order: 1. Pre-set tokens (`setAuthTokens`) 2. Direct auth callback (`onGetAuthTokens`) 3. OAuth auth code (`setAuthCode` or `onGetAuthCode` callback) When a miniapp calls `appboxo.pay()`, the SDK will call your `onPaymentRequest` callback. Process the payment and return the result. Payment status values: `'success'`, `'failed'`, or `'cancelled'`. ```typescript theme={"system"} const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", onPaymentRequest: async (paymentData) => { // Process payment with your backend const response = await fetch('/api/payments/process', { method: 'POST', body: JSON.stringify(paymentData) }); const result = await response.json(); return { ...paymentData, status: result.status, // 'success', 'failed', or 'cancelled' hostappOrderId: result.orderId, transactionId: result.transactionId, // optional }; }, }); // Optional: listen for payment completion sdk.onPaymentComplete((success, data) => { if (success) { console.log('Payment succeeded:', data); } }); ``` **Important Notes:** * When `onPaymentRequest` is set, the SDK automatically tells the miniapp it supports `AppBoxoWebAppPay`, so it can call `appboxo.pay()`. * **If `onPaymentRequest` is not configured**, payment requests will fail. Enable `debug: true` to see error messages. Controls miniapp theming to match your host app's design system or respect user preferences. The theme preference is passed to the miniapp via InitData and the miniapp is automatically notified when the theme changes. ```typescript theme={"system"} // Set theme during initialization const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", theme: "dark" // or 'light', 'system' }); // Or set theme dynamically sdk.setTheme("light"); ``` **Theme values:** * `'dark'`: Force dark mode * `'light'`: Force light mode * `'system'`: Use system preference (default) The theme is passed to the miniapp via `InitData.data.theme` on the next `AppBoxoWebAppGetInitData` request. If you call `setTheme()` after the miniapp has already loaded, the SDK will automatically notify the miniapp about the theme change via `postMessage`, allowing the miniapp to respond immediately without waiting for the next InitData request. **Important Notes:** * To ensure the theme is available immediately, set it during SDK initialization or before calling `mount()`. * The miniapp must implement theme handling logic to receive and apply the theme from `InitData.data.theme`. When users log out of your host app, you must completely clear all miniapp session data. ```typescript theme={"system"} sdk.logout(); ``` This clears the host app's `localStorage`, `sessionStorage`, and SDK's internal `authCode` and `authTokens`. The SDK provides a helper method to mount miniapps. The miniapp URL will be automatically fetched from the API: ```typescript theme={"system"} await sdk.mount({ container: '#miniapp-container', className: 'miniapp-iframe' }); ``` Or manually set iframe: ```typescript theme={"system"} const iframe = document.createElement('iframe'); iframe.src = await sdk.getMiniappUrl(); document.getElementById('miniapp').appendChild(iframe); sdk.setIframe(iframe); sdk.initialize(); ``` **Styling:** When using the `mount` helper, styling is handled via CSS: ```css theme={"system"} .miniapp-container { width: 100%; height: 500px; } .miniapp-iframe { width: 100%; height: 100%; border: none; } ``` Fetch the complete catalog of available miniapps with detailed metadata. ```typescript theme={"system"} // Note: This feature may require additional API integration // Check SDK documentation for latest implementation ``` Establish two-way communication between your host app and miniapps using custom events. ```typescript theme={"system"} sdk.onEvent('custom_event', (event) => { // Handle custom event from miniapp console.log('Custom event received:', event); // Send response back to miniapp if needed // (implementation depends on SDK version) }); ``` | Method | Description | | ------------------------------------- | --------------------------------------------------------------------------- | | `setAuthCode(code)` | Set authentication code | | `setAuthTokens(token, refreshToken?)` | Set authentication tokens directly | | `setLocale(locale)` | Set locale/language code (e.g., 'en', 'en-US', 'ru', 'zh-CN') | | `setTheme(theme)` | Set theme/color scheme preference ('dark' \| 'light' \| 'system') | | `onAuth(callback)` | Register callback for authentication events | | `mount(config)` | Create iframe and initialize SDK | | `getMiniappUrl()` | Fetch miniapp URL from API settings endpoint | | `setIframe(iframe)` | Set iframe element manually | | `initialize()` | Start listening for events | | `onEvent(type, handler)` | Register custom event handler | | `onLoginComplete(callback)` | Login completion callback | | `onPaymentComplete(callback)` | Payment completion callback | | `logout()` | Clear host app's localStorage, sessionStorage, and SDK's internal auth data | | `destroy()` | Clean up resources | SDK handles these miniapp events: * `AppBoxoWebAppLogin` - User authentication * `AppBoxoWebAppPay` - Payment processing * `AppBoxoWebAppGetInitData` - Initial data request * `AppBoxoWebAppCustomEvent` - Custom events Track key moments in a miniapp's execution: ```typescript theme={"system"} // Login completion sdk.onLoginComplete((success, data) => { if (success) { console.log('Login succeeded:', data); } else { console.log('Login failed:', data); } }); // Payment completion sdk.onPaymentComplete((success, data) => { if (success) { console.log('Payment succeeded:', data); } else { console.log('Payment failed:', data); } }); ``` ### OAuth Flow Example ```tsx theme={"system"} import { useEffect, useRef, useState } from "react"; import { AppboxoWebSDK } from "@appboxo/web-sdk"; import type { PaymentRequest, PaymentResponse } from "@appboxo/web-sdk"; function OAuthExample() { const containerRef = useRef(null); const sdkRef = useRef(null); const [isMounted, setIsMounted] = useState(false); useEffect(() => { const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", debug: false, allowedOrigins: [], // Empty array allows all origins onPaymentRequest: async (paymentData: PaymentRequest): Promise => { const response = await fetch('/api/payments/process', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(paymentData) }); const result = await response.json(); return { ...paymentData, status: result.status, hostappOrderId: result.hostappOrderId, }; }, }); // Set auth code (OAuth flow) sdk.setAuthCode("your-auth-code"); sdk.onLoginComplete((success, data) => { console.log('Login:', success ? 'success' : 'failed', data); }); sdk.onPaymentComplete((success, data) => { console.log('Payment:', success ? 'success' : 'failed', data); }); sdkRef.current = sdk; const mountMiniapp = async () => { if (containerRef.current) { try { await sdk.mount({ container: containerRef.current, className: "miniapp-iframe" }); setIsMounted(true); } catch (err) { console.error('Failed to mount miniapp:', err); } } }; mountMiniapp(); return () => { sdk.destroy(); }; }, []); return (

Status: {isMounted ? "Mounted" : "Mounting..."}

); } ``` ### Direct Auth Flow Example ```tsx theme={"system"} import { useEffect, useRef, useState } from "react"; import { AppboxoWebSDK } from "@appboxo/web-sdk"; import type { PaymentRequest, PaymentResponse } from "@appboxo/web-sdk"; function DirectAuthExample() { const containerRef = useRef(null); const sdkRef = useRef(null); const [isMounted, setIsMounted] = useState(false); useEffect(() => { const sdk = new AppboxoWebSDK({ clientId: "your-client-id", appId: "your-app-id", debug: false, // Alternative: Use onGetAuthTokens callback // onGetAuthTokens: async () => { // const response = await fetch('/api/get-miniapp-tokens'); // const result = await response.json(); // return { token: result.access_token, refresh_token: result.refresh_token }; // } }); // Direct auth flow - onAuth lifecycle hook sdk.onAuth(async () => { // Your backend calls Boxo Dashboard connect endpoint to get miniapp tokens const response = await fetch('/api/get-miniapp-tokens', { headers: { 'Authorization': `Bearer ${yourToken}` } }); const tokens = await response.json(); sdk.setAuthTokens(tokens.access_token, tokens.refresh_token); }); // Alternative: Pre-set tokens if you already have them // const tokens = await getTokensFromBackend(); // sdk.setAuthTokens(tokens.access_token, tokens.refresh_token); sdk.onLoginComplete((success, data) => { console.log('Login:', success ? 'success' : 'failed', data); }); sdkRef.current = sdk; const mountMiniapp = async () => { if (containerRef.current) { try { await sdk.mount({ container: containerRef.current, className: "miniapp-iframe" }); setIsMounted(true); } catch (err) { console.error('Failed to mount miniapp:', err); } } }; mountMiniapp(); return () => { sdk.destroy(); }; }, []); return (

Status: {isMounted ? "Mounted" : "Mounting..."}

); } ``` # Custom Events System Source: https://boxo.mintlify.app/host-apps/CES The custom events system is a powerful feature that enables bidirectional data communication between a **miniapp** and the **host app**. The **miniapp** can send data that the **host app** can recognize. Additionally, certain operations can be implemented at the native app level for enhanced functionality. [Custom events example](/miniapp/CES) ```swift theme={"system"} miniapp.delegate = self ... extension ViewController : MiniappDelegate { func didReceiveCustomEvent(miniapp: Miniapp, customEvent: CustomEvent) { customEvent.payload = [ "message" : "text", "id" : 123, "checked" : true ] miniapp.sendCustomEvent(customEvent: customEvent) } } ``` ```kotlin theme={"system"} miniApp.setCustomEventListener { _, miniapp, customEvent -> //doSomething customEvent.payload = mapOf("message" to "text", "id" to 123, "checked" to true) miniapp.sendEvent(customEvent) } ``` **java** ```java theme={"system"} miniapp.setCustomEventListener(new Miniapp.CustomEventListener() { @Override public void handle(@NotNull BoxoFragment boxoFragment, @NotNull MiniApp miniapp, @NotNull CustomEvent customEvent) { Map payload = new HashMap<>(); payload.put("message", "message"); payload.put("id", 123); payload.put("checked", true); customEvent.setPayload(payload); miniapp.sendEvent(customEvent); } }); ``` Handle custom events by listening to `.customEvents()`. Example receiving and sending back same event: ``` Appboxo.customEvents().listen((CustomEvent event) { if (event.appId == 'app123456') { event.payload = {"foo": "bar"}; Appboxo.sendEvent(event); } }); ``` For cases when you want to hide all miniapps when a custom event is received, you can call `Appboxo.hideMiniapps()`; Example: ```clike theme={"system"} import 'package:flutter/material.dart'; import 'package:appboxo_sdk/appboxo_sdk.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { @override void initState() { super.initState(); Appboxo.setConfig("CLIENT_ID"); Appboxo.customEvents().listen((CustomEvent event) { if (event.appId == 'app123456') { Appboxo.hideMiniapps(); Future.delayed(const Duration(milliseconds: 2000), () { Appboxo.openMiniapp("app123456", ""); event.payload = {"complete": "ok"}; Appboxo.sendEvent(event); }); } }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Appboxo SDK Test'), ), body: Center( child: RaisedButton( onPressed: () { Appboxo.openMiniapp("app123456", ""); }, child: Text("Miniapp"), ), ), ), ); } } ``` Handling custom events in React Native is straightforward. Use customEvents to both subscribe to and send custom events between the miniapp and the host app. Example: ```clike theme={"system"} appboxo.customEvents .subscribe<'eventType', { payloadKey: 'payloadData' }>(event => { const modifiedEvent = { app_id: '[miniap_id]', // miniapp id custom_event: { error_type: undefined, // throw the error with non empty 'error_type' payload: {payloadKey: 'payloadData'}, // payload data to send to miniapp request_id: '1', // event requet id type: 'eventType', // event type }, } appboxo.customEvents.send(modifiedEvent) // your data that you want to send back to miniapp }) ``` > TIP > > Please don't forget to unsubscribe from events Usage: ```clike theme={"system"} import React from 'react'; import appboxo from '@appboxo/react-native-sdk'; import { StyleSheet, View, Button } from 'react-native'; type eventType = 'eventType'; type eventPayload = { payloadKey: 'payload' }; export default function App() { React.useEffect(() => { appboxo.setConfig('[client_id]'); //set your Appboxo client_id const eventPayloadData = { payloadKey: 'payload' }; const subscription = appboxo.customEvents .subscribe( //listen custom event from miniapp event => { const modifiedEvent = { app_id: '[miniap_id]', // miniapp id custom_event: { request_id: event.custom_event.request_id, // event requet id payload: eventPayloadData, // payload data to send to miniapp type: eventType, // event type }, }; appboxo.customEvents.send(modifiedEvent); //send custom event to miniapp }, (errorType?: string) => { console.error(errorType || 'Something went wrong!'); //handle error } ); return () => subscription(); //unsubscribe from custom events }, []); const handleOpenMiniapp = () => { appboxo.openMiniapp('[miniapp_id]', '[auth_payload]'); //launch miniapp by id with auth payload } return (