Wrapply logoWrapply Tutorials
πŸ’³ Store payments

Integrazione acquisti in-app: da sito web ad app Flutter

Questa guida spiega come preparare gli acquisti in-app nativi in un’app Wrapply: prodotti store, product ID, chiamate di acquisto, ripristino e validazione ricevute lato backend.

Comandi bridge per acquisti in-app

Quando abiliti il modulo acquisti in-app, l'app generata espone veri comandi JavaScript dentro la WebView. Il sito li chiama e poi il backend deve verificare l'acquisto e sbloccare la funzione pagata.

ComandoUsoPayloadRisposta tipica
window.Wrapply.iap.getProducts(payload)Legge i prodotti configurati su Google Play o App Store{ productIds: ['premium_monthly'] }{ ok, available, products, notFoundIds }
window.Wrapply.iap.purchase(payload)Avvia il flusso di acquisto nativo{ productId, consumable, applicationUserName }{ ok, purchaseStarted, product }
window.Wrapply.iap.restorePurchases(payload)Ripristina acquisti non consumabili o abbonamenti{ applicationUserName }{ ok, restoreStarted, latestPurchases }
window.Wrapply.iap.getStatus(payload)Controlla se il billing store Γ¨ disponibile e legge gli ultimi eventi{}{ ok, available, latestPurchases }

Configurazione store necessaria

Crea i prodotti in Google Play Console e App Store Connect usando gli stessi product ID usati dal sito. Testa su dispositivi reali e valida le ricevute lato server prima di sbloccare abbonamenti, crediti o contenuti premium.

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

onWrapplyReady(async (Wrapply) => {
if (!Wrapply.iap) return;
const products = await Wrapply.iap.getProducts({ productIds: ['premium_monthly', 'credits_10'] });
console.log(products);
});
async function buyPremium(currentUser) {
if (!window.Wrapply?.iap) return showWebCheckoutFallback();
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)
});
}
async function restoreNativePurchases(currentUser) {
if (!window.Wrapply?.iap) return;
const restored = await window.Wrapply.iap.restorePurchases({
applicationUserName: currentUser.id
});
await fetch('/api/iap/restore', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(restored)
});
}

Esempi di integrazione

Puoi usare lo stesso pattern bridge in JavaScript, React, Vue, Angular, PHP/Laravel, WordPress o jQuery. La parte importante Γ¨ attendere il bridge nativo prima di chiamarlo.

JavaScript

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

Hook 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 };
}

Composable Vue

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

Service Angular

@Injectable({ providedIn: 'root' })
export class WrapplyBridgeService {
async callNative(payload = {}) {
if (!window.Wrapply?.iap) return { ok: false, error: 'Bridge unavailable' };
return window.Wrapply.iap.getStatus(payload);
}
}

jQuery

$('#wrapply-action').on('click', async function () {
if (!window.Wrapply?.iap) return;
const result = await window.Wrapply.iap.getStatus({});
$('#wrapply-output').text(JSON.stringify(result, null, 2));
});

CMS / template backend

<button onclick="runNativeFeature(window.currentUser)">Open app feature</button>
<script>
window.addEventListener('wrapplyNativeBridgeReady', function () {
document.body.classList.add('wrapply-native-app');
});
</script>
Importante: il bridge funziona dentro la WebView dell'app generata, non nella versione pubblica del sito aperta da browser.
Quando abiliti funzionalitΓ  native, lo ZIP generato include anche WRAPPLY_NATIVE_BRIDGE_GUIDE.pdf con moduli attivi, chiamate esatte e note di implementazione per il cliente.