Wrapply logoTutoriales Wrapply
🧩 Bridge nativo

API Bridge de Wrapply: conecta tu sitio con funciones nativas

Guía práctica de las API bridge nativas de Wrapply para notificaciones, deeplinks, enlaces entrantes, compras in-app y ubicación en apps Flutter generadas.

Referencia del Native Bridge

La app Flutter generada expone window.Wrapply dentro del WebView. Tu sitio puede llamar a este objeto para usar funciones nativas solo cuando el módulo correspondiente está activado. Espera siempre wrapplyNativeBridgeReady y gestiona siempre { ok:false, error } como un caso normal de fallback.

APICuándo usarlaEntradaRespuesta
window.Wrapply.isNativeApp()Detecta el wrapper nativononetrue inside app
notifications.requestPermission(payload)Solicita permiso de notificaciones{ provider }{ ok, permission, granted }
notifications.getToken(payload)Lee o actualiza el token del dispositivo{ provider, refresh? }{ ok, token, provider }
notifications.refreshToken(payload)Regenera el token. Alias: updateToken{ provider }{ ok, token, refreshed:true }
notifications.show(payload)Muestra una notificación local inmediata{ title, body?, data? }{ ok, shown:true }
notifications.getStatus(payload)Lee estado de proveedor y permisos{ provider }{ ok, granted, configured? }
iap.getProducts(payload)Lee productos configurados en la tienda{ packageName, productIds }{ ok, available, products }
iap.purchase(payload)Inicia una compra in-app{ packageName, productId, consumable? }{ ok, purchaseStarted }
iap.restorePurchases(payload)Restaura compras no consumibles{ packageName }{ ok, latestPurchases }
deepLinks.open(payload)Abre URL interna, externa, teléfono, email o WhatsApp{ type, url/value }{ ok, type, url }
wrapply://open/pathAbre la app instalada desde email, SMS o sitio externoexternal linkloads https://DOMAIN/path
Cuando activas funciones bridge, Wrapply también entrega un PDF con módulos activos, llamadas exactas, configuración del proveedor y notas para revisión en las tiendas.

Proveedores de notificaciones

El sitio puede elegir el proveedor de notificaciones en cada llamada. Wrapply incluye solo el proveedor seleccionado en la app generada.

ProveedorUsoConfiguración requeridaNota importante
localDefault seguro, token local guardado en shared preferencesSin archivo externoÚtil para pruebas/sesión; no es un token push remoto real
firebaseProveedor Firebase Cloud Messagingandroid/app/google-services.json y opcional ios/Runner/GoogleService-Info.plistSi faltan archivos, devuelve ok:false/configured:false
onesignalProveedor OneSignalOneSignal App ID en configuración/buildRequiere setup OneSignal antes de enviar push remotas

Permisos del dispositivo

Cámara, micrófono y geolocalización usan APIs web estándar. El wrapper añade los permisos nativos Android/iOS cuando la función está activa.

FunciónAPI webPermisos nativosComportamiento
Cámaranavigator.mediaDevices.getUserMedia({ video:true })Android CAMERA, iOS NSCameraUsageDescriptionUsa API web estándar; la app gestiona el prompt nativo
Micrófononavigator.mediaDevices.getUserMedia({ audio:true })Android RECORD_AUDIO, iOS NSMicrophoneUsageDescriptionUsa API web estándar; no requiere llamada directa a Wrapply
Geolocalizaciónnavigator.geolocation.getCurrentPosition(...)Android COARSE/FINE, texto iOS location usageLa ubicación precisa es opcional y solo debe activarse si hace falta

Ejemplos por tipo de código

Estos ejemplos son pequeños a propósito: muestran el patrón correcto de integración, mientras el PDF generado enumera los módulos activos para esa app.

Ready helper

function onWrapplyReady(callback) {
if (window.Wrapply && window.Wrapply.__nativeBridgeReady) {
callback(window.Wrapply);
return;
}
window.addEventListener("wrapplyNativeBridgeReady", () => {
callback(window.Wrapply);
}, { once: true });
}

JavaScript

document.querySelector("#notify").addEventListener("click", async () => {
if (!window.Wrapply?.notifications) return alert("Available inside the app");
const permission = await window.Wrapply.notifications.requestPermission({ provider: "firebase" });
if (!permission.ok || !permission.granted) return;
const token = await window.Wrapply.notifications.getToken({ provider: "firebase" });
await fetch("/api/device-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: token.token, platform: "wrapply" })
});
});

TypeScript

type WrapplyResponse = Promise<Record<string, unknown>>;
declare global {
interface Window {
Wrapply?: {
__nativeBridgeReady?: boolean;
isNativeApp: () => Promise<boolean>;
notifications?: {
requestPermission: (p: Record<string, unknown>) => WrapplyResponse;
getToken: (p: Record<string, unknown>) => WrapplyResponse;
refreshToken: (p: Record<string, unknown>) => WrapplyResponse;
updateToken: (p: Record<string, unknown>) => WrapplyResponse;
show: (p: Record<string, unknown>) => WrapplyResponse;
getStatus: (p: Record<string, unknown>) => WrapplyResponse;
};
iap?: { purchase: (p: Record<string, unknown>) => WrapplyResponse };
deepLinks?: { open: (p: Record<string, unknown>) => WrapplyResponse };
};
}
}
export {};

React

import { useEffect, useState } from "react";
export function useWrapplyBridge() {
const [ready, setReady] = useState(false);
useEffect(() => {
if (window.Wrapply?.__nativeBridgeReady) return setReady(true);
const onReady = () => setReady(true);
window.addEventListener("wrapplyNativeBridgeReady", onReady);
return () => window.removeEventListener("wrapplyNativeBridgeReady", onReady);
}, []);
return { ready, Wrapply: ready ? window.Wrapply : null };
}

Vue 3

import { ref, onMounted, onBeforeUnmount } from "vue";
export function useWrapplyBridge() {
const ready = ref(false);
const markReady = () => { ready.value = true; };
onMounted(() => {
if (window.Wrapply?.__nativeBridgeReady) markReady();
else window.addEventListener("wrapplyNativeBridgeReady", markReady);
});
onBeforeUnmount(() => window.removeEventListener("wrapplyNativeBridgeReady", markReady));
return { ready };
}

Angular

@Injectable({ providedIn: "root" })
export class WrapplyBridgeService {
async requestToken(provider = "firebase") {
if (!window.Wrapply?.notifications) {
return { ok: false, error: "Bridge unavailable" };
}
return window.Wrapply.notifications.getToken({ provider });
}
}

jQuery

$("#wrapply-token").on("click", async function () {
if (!window.Wrapply?.notifications) return;
const result = await window.Wrapply.notifications.getToken({ provider: "local" });
$("#wrapply-output").text(JSON.stringify(result, null, 2));
});

PHP / Laravel Blade

<button onclick="buyNativeProduct()">Buy premium</button>
<script>
async function buyNativeProduct() {
if (!window.Wrapply?.iap) return;
const result = await window.Wrapply.iap.purchase({
packageName: "{{ config('app.mobile_package') }}",
productId: "premium_monthly",
consumable: false
});
console.log(result);
}
</script>

WordPress

add_action('wp_footer', function () { ?>
<script>
window.wrapplyNotify = async function () {
if (!window.Wrapply?.notifications) return;
return window.Wrapply.notifications.show({
title: "WordPress",
body: "Notification called from theme/plugin"
});
};
</script>
<?php });

Deep links

// External links from email, SMS, CRM or website
wrapply://open/profile
wrapply://open/checkout?plan=premium
wrapply://open/orders/123

// Native action inside the app
await window.Wrapply.deepLinks.open({ type: "internal_url", url: "https://example.com/account" });
await window.Wrapply.deepLinks.open({ type: "mailto", value: "support@example.com" });
await window.Wrapply.deepLinks.open({ type: "tel", value: "+390000000000" });
await window.Wrapply.deepLinks.open({ type: "whatsapp", value: "+390000000000" });

Qué hace el bridge de Wrapply

El bridge expone una API JavaScript dentro del WebView. Tu sitio puede llamar window.Wrapply y la app Flutter ejecuta la acción nativa solo si la función fue activada.

Al seleccionar funciones bridge, Wrapply también entrega una guía PDF con llamadas exactas, módulos activos y notas de configuración.

Activa solo los módulos necesarios

Notifications
Local/Firebase/OneSignal provider, permission request, token read/refresh and local notification display.
Actions and deeplinks
Open internal WebView URLs, external browser URLs, phone, email and WhatsApp from your website.
Inbound links
Open the installed app from a configured scheme or app link, then route the user to the right page.
In-app purchases
Query store products, start purchase, restore purchases and send results to your backend for validation.
Location
Add the native permission base for maps, nearby results or geolocation flows.

Setup flow

1. Configure features

Enable only the modules you need in the Wrapply configurator.

2. Add required files

Upload Firebase files or provider identifiers when the selected provider requires them.

3. Generate source code

Wrapply writes conditional dependencies, AndroidManifest entries, Info.plist keys and bridge modules.

4. Add JavaScript calls

Call window.Wrapply from your website only after checking the bridge exists.

5. Test before publishing

Test native permissions, tokens, purchases and links on real Android/iOS devices.

Ejemplos JavaScript reales

Use these calls from your website only after verifying that window.Wrapply exists.

Notifications

async function enablePush() {
if (!window.Wrapply?.notifications) return;
await window.Wrapply.notifications.requestPermission({ provider: 'firebase' });
const token = await window.Wrapply.notifications.getToken({ provider: 'firebase' });
await fetch('/api/device-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token.token, platform: 'app' })
});
}
window.Wrapply?.notifications?.show({ title: 'Order updated', body: 'Your request is ready' });

Actions and deeplinks

window.Wrapply?.deepLinks?.open({ type: 'internal_url', url: 'https://example.com/account' });
window.Wrapply?.deepLinks?.open({ type: 'mailto', value: 'support@example.com' });
window.Wrapply?.deepLinks?.open({ type: 'tel', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'whatsapp', value: '+390000000000' });
window.Wrapply?.deepLinks?.open({ type: 'url', url: 'https://example.com/help' });

In-app purchases

async function buyPremium() {
if (!window.Wrapply?.iap) return;
await window.Wrapply.iap.getProducts({ productIds: ['premium_monthly'] });
const result = await window.Wrapply.iap.purchase({
productId: 'premium_monthly',
consumable: false,
applicationUserName: currentUser.id
});
await fetch('/api/iap/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result)
});
}

Location

if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
console.log(position.coords.latitude, position.coords.longitude);
});
}

Qué recibes con funciones bridge

Conditional source code
Only selected dependencies, permissions and bridge files are included.
Configuration files
Firebase files, OneSignal App ID and iOS optional files are inserted only when requested.
PDF implementation guide
Al seleccionar funciones bridge, Wrapply también entrega una guía PDF con llamadas exactas, módulos activos y notas de configuración.
Store review support
Payment, notification and permission modules should be tested before publishing.

FAQ bridge

Does the bridge work on the public website?

No. It works inside the generated app WebView. Always check window.Wrapply before calling native APIs.

Do I need a backend?

For Firebase push and in-app purchase validation, yes. The app exposes tokens and purchase events, but the backend should send messages and validate receipts.

Can Wrapply implement it?

Yes. Managed publishing can include configuration, testing and documentation for the enabled bridge modules.

Ready to connect native features?

Guía práctica de las API bridge nativas de Wrapply para notificaciones, deeplinks, enlaces entrantes, compras in-app y ubicación en apps Flutter generadas.