Buongiorno a tutti,
Scrivo questo post perchè di recente mi sono dovuto scontrare con la gestione degli acquisti in app da parte di Google e Apple, e visto che l’argomento è ostico e la documentazione scarseggia ho pensato potesse essere utile una “guida” per chi si dovesse cimentare nella stessa impresa su InDe Cloud.
Per prima cosa bisogna scegliere un plugin di cordova da implementare.
La nostra scelta è ricaduta su Cordova Plugin Purchase (trovate la documentazione su In App Purchase 2 - Awesome Cordova Plugins) perchè è un progetto nella documentazione ufficiale di ionic, che viene mantenuto aggiornato e che ci sembrava avesse tutto ciò che faceva al caso nostro.
Ulteriore documentazione con esempi si può trovare al link https://purchase.cordova.fovea.cc
Come seconda cosa bisogna implementare il plugin, quindi nel progetto InDe di riferimento bisognerà :
- Aggiungere una libreria di tipo applicazione
- Aggiungere una classe a questa libreria : questa classe verrà chiamata dal codice lato client
- Aggiungere una risorsa di tipo Plugin
- Tornando nell’app, dentro AppObjects->device, sarà apparso un plugin con il nome della classe che abbiamo inserito prima : nel campo parametri andrà inserito cordova-plugin-purchase, o più in generale il comando che dirà a cordova che plugin aggiungere.
- Ora il server genererà i file IPA e APK con il plugin aggiornato e con i permessi richiesti (nel nostro caso quello degli acquisti in app)
- Nella classe che abbiamo creato in precedenza dobbiamo aggiungere una serie di funzioni alias : queste verranno chiamate dall’app e a loro volta chiameranno i metodi del plugin
- Nel caso la funzione importata debba ritornare qualche valore possiamo usare req.setResult(x) per ritornare il valore, mentre se ha delle callback dobbiamo impostarle noi dentro al codice della funzione alias e gestirne il comportamento di conseguenza.
Bene, questa è la guida generica di come implementare un plugin Cordova partendo da zero, ma per implementare gli acquisti in app abbiamo bisogno di un altro paio di passaggi ![]()
- Bisogna avere un’applicazione caricata sulla google developer console e su app store connect, anche solo su Testflight o come test interno : in questo modo possiamo generare degli acquisti in app legati alla firma dell’applicazione e questi verranno riconosciuti in fase di test
- Per evitare di spendere soldi veri, bisogna generare degli account di test dove possiamo testare i vari casi per gli acquisti in app (carta approvata, declinata, acquisto immediato o in ritardo…), Anche per questo vi lascio due link utili : Test your Google Play Billing Library integration | Google Play's billing system | Android Developers e Testing in-app purchases with sandbox | Apple Developer Documentation
- Ora dobbiamo solamente compilare i dati bancari relativi a entrambi gli store e pubblicare degli acquisti in app nell’apposita sezione di entrambi gli store : una volta che questi saranno in uno stato “pronto per l’invio” o con bollino verde, potremo vederli in app (ci vogliono un pò di ore prima che vengano abilitati)
- La documentazione del plugin (linkata a inizio post) specifica bene le differenze tra i vari tipi di IAP ed è più dettagliata a questo riguardo, quindi se avete dubbi vi rimando a quella
Bene, ora abbiamo finito i preparativi! ![]()
Passando al codice in sè, la nostra libreria usa un sistema simile alle promise per gestire il flusso degli acquisti in app, i miei consigli per lo sviluppo sono i seguenti :
- Come prima funzione da implementare, se usate un launcher con update Live, consiglio una funzione che controlla se app.device.nomeplugin è disponibile : se c’è allora sono un file che ha il plugin e può usare le relative funzioni, altrimenti no e quindi posso disattivare le relative funzioni nel codice per evitare errori.
- Subito dopo, bisogna registrare i prodotti usando l’ID dell’acquisto in app inserito su entrambi gli store, io consiglio di tenere lo stesso su tutti gli store per comodità e una manutenzione più agevole.
Per farlo bisogna impostare una funzione alias che al suo interno chiama store.register, come ad esempio
store.register({
type: store.CONSUMABLE,
id: req.params.inappPurchaseID
});
- In questo modo abbiamo creato un consumabile a cui abbiamo associato un ID, e stiamo dicendo all’app che il prodotto ha quell’ID quindi può prendersi i relativi valori dal server.
- Dopodichè ci servono dei listener da associare ai vari stati della transazione del prodotto : sempre tramite una funzione alias, implementiamo questa funzione :
store.when(req.params.inappPurchaseID)
.updated(function () {
console.log(“Prodotto aggiornato”);
})
- La funzione fa uso delle promise per monitorare lo stato dell’acquisto , come esempio banale ho usato un console log quando cambia lo stato del prodotto, ma ovviamente vanno implementate soluzioni diverse in base allo stato in cui il prodotto si trova e dettagli ulteriori si possono trovare nella documentazione del plugin.
- Una volta fatto questo dobbiamo chiamare store,refresh tramite un’altra funzione alias, per tenere l’app aggiornata con gli stati degli acquisti in app e iniziare effettivamente ad ascoltare gli IAP registrati in precedenza
*Quasi finito! Nella pagina di acquisto del prodotto dobbiamo sempre chiamare tramite alias il metodo store.get(req.params.inappPurchaseID) così da avere i dati dell’acquisto in app come li vede il server e permetterci di usarli nella schermata (ad esempio per fare vedere il prezzo sul bottone di acquisto) - Sul bottone di acquisto, bisogna chiamare tramite alias store.order(req.params.inappPurchaseID); e basta! In questo modo l’acquisto verrà processato in automatico, e una volta che il suo stato cambierà in acquistato o in errore verrà aggiornata la funzione di ascolto che abbiamo impostato prima, che eseguirà il codice a sua volta
Le ultime considerazioni :
- Gli acquisti in app possono essere testati SOLO su un apk o ipa installati sul dispositivo fisico, emulatori o instalauncher non funzioneranno purtroppo.
- Può essere utile bloccare la videata in fase di acquisto, a me piace usare un app.popup di tipo “loading” da cancellare in seguito una volta risolto il flusso dell’acquisto in app.
- A tal proposito nei commenti metto un modo per far comunicare tra di loro le promise con la videata dove si trova il bottone, per gestirne il click e i vari comportamenti
Questo è quanto! Spero di essere stato utile, se qualcuno ha domande può farle qui sotto e cercherò di rispondere al meglio!
