<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BEWIZYU | Agence Digitale</title>
    <description>The latest articles on DEV Community by BEWIZYU | Agence Digitale (@bewizyu).</description>
    <link>https://dev.to/bewizyu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F959%2F4be09d47-33ea-4326-94b0-fb6c7f09fb5a.jpg</url>
      <title>DEV Community: BEWIZYU | Agence Digitale</title>
      <link>https://dev.to/bewizyu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bewizyu"/>
    <language>en</language>
    <item>
      <title>Quoi de neuf dans Laravel 8 ?</title>
      <dc:creator>Yacine ALHYANE</dc:creator>
      <pubDate>Mon, 19 Apr 2021 12:22:46 +0000</pubDate>
      <link>https://dev.to/bewizyu/quoi-de-neuf-dans-laravel-8-k5n</link>
      <guid>https://dev.to/bewizyu/quoi-de-neuf-dans-laravel-8-k5n</guid>
      <description>&lt;p&gt;Le 8 septembre 2020, la version 8 de Laravel est sortie, qui dispose de nouvelles fonctionnalités telles que le répertoire des modèles, l'ecrasement des migrations (Squashing), les jobs batch, des améliorations en mode maintenance, des composants dynamiques dans les templates Blade, améliorations des écouteurs d'événements, etc.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Release&lt;/th&gt;
&lt;th&gt;Bug Fixes Until&lt;/th&gt;
&lt;th&gt;Security Fixes Until&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;6 (LTS)&lt;/td&gt;
&lt;td&gt;September 3rd, 2019&lt;/td&gt;
&lt;td&gt;September 7th, 2021&lt;/td&gt;
&lt;td&gt;September 6th, 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;March 3rd, 2020&lt;/td&gt;
&lt;td&gt;October 6th, 2020&lt;/td&gt;
&lt;td&gt;March 3rd, 2021&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;September 8th, 2020&lt;/td&gt;
&lt;td&gt;March 1st, 2022&lt;/td&gt;
&lt;td&gt;September 6th, 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9 (LTS)&lt;/td&gt;
&lt;td&gt;September, 2021&lt;/td&gt;
&lt;td&gt;September, 2023&lt;/td&gt;
&lt;td&gt;September, 2024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;September, 2022&lt;/td&gt;
&lt;td&gt;March, 2024&lt;/td&gt;
&lt;td&gt;September, 2024&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
Laravel Releases Calendar



&lt;p&gt;Dans cet article, je vais vous parler de tous les détails de certaines de ces nouvelles fonctionnalités.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Laravel Jetstream&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Il s’agit d’un package de scaffolding qui vous permet de créer rapidement les fonctionnalités de connexion, d’enregistrement, de vérification d’e-mail, d’authentification à 2 étapes, de gérer les sessions, le support API via &lt;a href="https://laravel.com/docs/8.x/sanctum"&gt;Laravel Sactum&lt;/a&gt; et éventuellement la gestion des équipes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Laravel Jetstream&lt;/code&gt; remplace et améliore le package de scaffolding que Laravel avait dans les versions précédentes avec l’interface utilisateur, qui a été créée avec &lt;a href="https://tailwindcss.com/"&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Laravel Jetstream&lt;/code&gt; est venue avec deux choix de stacks frontend &lt;a href="https://laravel-livewire.com/"&gt;Livewire + Blade&lt;/a&gt; ou  &lt;a href="https://inertiajs.com/"&gt;Inertia.js + Vue.js&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Comment utiliser laravel Jetstream?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Vous pouvez créer une nouvelle application avec Jetstream à l’aide du programme d’installation de Laravel. Assurez-vous que le programme d’installation de Laravel est mis à jour vers la v4.0, puis exécutez ce qui suit:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;laravel new my-project -jet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Choisissez le stack que vous souhaitez utiliser: &lt;code&gt;Livewire&lt;/code&gt; ou &lt;code&gt;Inertia&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ensuite, exécutez vos migrations de base de données avec:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Finalement, consultez votre application sur &lt;code&gt;http://localhost:8000&lt;/code&gt; en exécutant:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. Un répertoire pour les Models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;À la demande de la communauté, le squelette d’un projet Laravel comprend désormais un répertoire pour les modèles, toutes les commandes pertinentes ont été mises à jour pour supposer que les modèles existent dans le répertoire, s’il existe. Si le répertoire des modèles n’existe pas, Laravel supposera que les modèles sont placés directement dans le répertoire de l’application app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2Crx8V2R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Amx5O0armKV9kCKZGgJjFvA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2Crx8V2R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Amx5O0armKV9kCKZGgJjFvA.png" alt="Nouveau repertoire Models"&gt;&lt;/a&gt; Nouveau repertoire Models&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Les classes Model Factories&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Les &lt;strong&gt;Model factories&lt;/strong&gt; ont été complètement réécrite comme des classes au lieu des fonctions, les model factories ont été améliorés pour soutenir les relations de premier-ordre (first-class relationship), par exemple &lt;em&gt;UserFactory&lt;/em&gt; inclus dans Laravel est écrit comme suit :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Grâce à la nouvelle &lt;em&gt;fonctionnalité&lt;/em&gt; HasFactory disponible dans les modèles générés, les model factories peuvent être utilisées de la manière suivante:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User::factory()-&amp;gt;count(20)-&amp;gt;create();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;4. Migration écrasée&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Laravel 8 introduit une autre fonctionnalité intéressante: l’écrasement des migrations! Vous n’avez plus à manipuler beaucoup de fichiers de migration lorsque vous ouvrez votre dossier de migrations! Grâce à l’écrasement de la migration, vous pouvez désormais condenser vos fichiers de migration en un seul fichier SQL avec les commandes suivantes:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# condensation de migration
php artisan schema:dump

# Vider le schéma de base de données actuel et élaguer toutes 
# les migrations existantes
php artisan schema:dump --prune
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Après avoir exécuté la première commande ci-dessus, Laravel 8 crée un fichier de &lt;em&gt;schéma&lt;/em&gt; dans le répertoire de &lt;strong&gt;&lt;em&gt;database/schema&lt;/em&gt;&lt;/strong&gt; et lorsque vous essayez de migrer votre base de données et qu’aucune autre migration n’a été exécutée, Laravel exécutera d’abord le SQL du fichier de &lt;em&gt;schéma&lt;/em&gt;, ensuite il exécutera les migrations restantes qui ne faisaient pas partie de la condensation…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Limitation de débit (Improved Rate Limiting)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Laravel 8 apporte des améliorations à la fonctionnalité de limitation de débit (rate limiting) existante tout en prenant en charge la rétrocompatibilité avec le middleware Throttle et en offrant beaucoup plus de flexibilité.&lt;/p&gt;

&lt;p&gt;Vous pouvez définir vos limiteurs de débit dans le fichier &lt;code&gt;app/Providers/RouteServiceProvider.php&lt;/code&gt; comme suit:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Vous pouvez ensuite appliquer cette configuration prédéfini aux routes Laravel avec le Throttling Middleware&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;6. Les mises à jour de Routing Namespace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dans les version précédentes de Laravel, la propriété &lt;code&gt;$namespace&lt;/code&gt; de la classe RouteServiceProvider contenait la valeur &lt;code&gt;App\Http\Controllers&lt;/code&gt;. Cette propriété s’ajoutait automatiquement en tant que préfixe namespace dans les définitions des contrôleurs dans les routes.&lt;/p&gt;

&lt;p&gt;Laravel 7:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/users', 'UserController@index');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Dans ce cas Laravel 7  considérera que la classe UserController appartient au namespace défini par la propriété &lt;code&gt;$namespace&lt;/code&gt; de RouteServiceProvider qui est par défaut: &lt;code&gt;App\Http\Controllers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dans Laravel 8, cette propriété a la valeur par défaut de &lt;code&gt;null&lt;/code&gt;, cela signifie que Laravel n’effectuera aucun préfixage automatique du namespace des contrôleurs. Par conséquent, dans les nouvelles applications Laravel 8, les définitions de namespace du contrôleur doivent être définies à l’aide de la syntaxe callable de PHP pour spécifier le namespace complet:&lt;/p&gt;

&lt;p&gt;Laravel 8:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;7. Des Helpers pour le Time Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lors des tests dans Laravel, vous deviez parfois modifier l’heure obtenue avec la méthode &lt;code&gt;now()&lt;/code&gt; ou effectuer des tests dans le futur ou dans le passé. Laravel 8 inclut désormais des Helpers qui permettent à votre application de voyager dans le temps et de manipuler l’heure actuelle.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8. Les améliorations du Mode Maintenance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dans les versions précédentes de Laravel, vous deviez spécifier les adresses IP qui sont autorisées à accéder à l’application quand elle est en mode maintenance avec la commande:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan down --allow=192.168.1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Laravel 8 apporte quelques améliorations à cette fonctionnalité, vous n’avez plus besoin d’autoriser seulement certaines adresses IP. Au lieu de ça, vous pouvez utiliser l’option secret de la commande php artisan down pour créer un access token pour l’application au mode maintenance:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan down --secret='Y7oXZapnys25F9qCdr18h3uKjsT8U9Ow'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;9. Distribution des Jobs par lots (Job batching)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Laravel 8 est également livrée avec une fonctionnalité qui permet de distribuer un groupe de jobs à exécuter en parallèle.&lt;/p&gt;

&lt;p&gt;Pour utiliser la nouvelle fonctionnalité, définissez d’abord un job comme vous le faisiez avant. L’exemple ci-dessous a été simplifié pour montrer l’utilisation du nouveau trait Batchable :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Maintenant vous pouvez distribuer votre job en utilisant la méthode &lt;code&gt;batch&lt;/code&gt; de la facade &lt;code&gt;Bus&lt;/code&gt;. Et pour surveiller la progression des jobs, vous pouvez utiliser les méthodes &lt;code&gt;then&lt;/code&gt;, &lt;code&gt;catch&lt;/code&gt; et &lt;code&gt;finally&lt;/code&gt; pour définir des callbacks de completion des jobs.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Dans cet article, nous avons cité les principales nouvelles fonctionnalités de Laravel 8, pour en savoir plus vous pouvez consulter le Release Notes sur la &lt;a href="https://laravel.com/docs/8.x/releases"&gt;documentation officielle de Laravel &lt;/a&gt;, et je vous donne rendez-vous en Septembre pour vous parler de laravel 9.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IppFwJ13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfmt1w5r6r60fvqmauco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IppFwJ13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfmt1w5r6r60fvqmauco.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>Comment bien choisir sa CI/CD Mobile en 2019</title>
      <dc:creator>Raphaël Bonaventure</dc:creator>
      <pubDate>Tue, 13 Apr 2021 17:12:22 +0000</pubDate>
      <link>https://dev.to/bewizyu/comment-bien-choisir-sa-ci-cd-mobile-en-2019-3knp</link>
      <guid>https://dev.to/bewizyu/comment-bien-choisir-sa-ci-cd-mobile-en-2019-3knp</guid>
      <description>&lt;p&gt;Intro : Quand on pense DevOps on pense souvent Cloud, Infra, Web, Backend, mais le monde du mobile a ses propres contraintes et ses propres outils. Nous allons voir quels sont les critères qui vont nous permettre de choisir la plateforme idéale.&lt;/p&gt;

&lt;p&gt;Plusieurs questions viennent en tête au moment de choisir la meilleur plateforme, dont :&lt;/p&gt;

&lt;p&gt;Est-ce que la solution répond à l’ensemble des mes besoins, combien ça va me coûter, quelles ressources seront nécessaires pour faire tourner le bouzin, combien de temps ça va faire gagner à mes équipes (ROI pour les businessmen), qui contacter en cas de pépin, comment assurer la pérennité de mon investissement et j’en passe.&lt;/p&gt;

&lt;p&gt;On vous propose de répondre à ces questions via un Benchmark maison !&lt;/p&gt;

&lt;h2&gt;
  
  
  Quelques bases
&lt;/h2&gt;

&lt;p&gt;Pour commencer (parce qu’il faut bien commencer quelques part), qu’est-ce qu’on entend par CI/CD et par Mobile ?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1 ) D’après Wikipédia, l’intégration continue est un ensemble de pratiques utilisées en génie logiciel consistant à vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression dans l’application développée.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;En résumé dans notre contexte, ca veut dire qu’on veut builder nos applications, vérifier que la qualité du code est bonne, que nos fonctionnalités sont utilisables via des tests automatisés et que l’on est capable de publier tout ça à nos utilisateurs automatiquement.&lt;/p&gt;

&lt;p&gt;À date, les principales plateformes disponibles sont :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xPugBqHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AzQFd5DbnQvCXOgb5l7PSBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xPugBqHf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AzQFd5DbnQvCXOgb5l7PSBw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👇 Présentation des plateformes pour ceux qui ne les connaissent pas 👇&lt;br&gt;
&lt;a href="https://instabug.com/blog/continuous-integration-tools/"&gt;&lt;strong&gt;Top Mobile Continuous Integration (CI/CD) Tools | Instabug Blog&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Discover the top continuous integration tools that help you speed up your development to deployment cycle and reduce…&lt;/em&gt; instabug.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans leurs modes de fonctionnement on peut regrouper ces plateformes selon 3 catégories :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Packagés&lt;/strong&gt; : Bitrise, App Center, Codeship&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modulaires&lt;/strong&gt; : Travis CI, Circle CI&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;On-Premise&lt;/strong&gt; : Jenkins, Gitlab CI, TeamCity&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;2) Mobile, toujours d’après Wikipédia, qualifie tout objet apte à se déplacer.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bon ça va pas nous aider… On va vous donner notre version ; par technologies mobiles on entend les principaux moyens de créer une application mobile à faire tourner sur vos précieux smartphones (du coup je parle pas de Windows Phone 😉).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;De nos jours, actuellement, en 2019, au jour d’aujourd’hui, ça veut dire : Android Natif, iOS Natif, Cordova (et bien souvent Ionic), React Native, Flutter, Xamarin à la limite, et point barre, le reste c’est ≤💩.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hwDxGmEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3396/1%2ABQHHmekhBtR30cEGG3xRtQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hwDxGmEW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3396/1%2ABQHHmekhBtR30cEGG3xRtQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notez que l’on a aussi besoin des outils qui les accompagnent, dont : XCode, le SDK Android, les différents frameworks que vous utilisez, plus les utilitaires dont vous pourriez avoir besoin (Git, Java, Gradle, Ruby, CocoaPods, etc…).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quelques chiffres sur le monde du mobile pour ceux que ca intéresse :&lt;br&gt;
&lt;a href="https://ionicframework.com/survey/2018#results"&gt;&lt;strong&gt;Ionic Framework - 2018 Developer Survey&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base…&lt;/em&gt; ionicframework.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Maintenant qu’on a dit ça, voyons comment affiner notre choix en fonction de nos besoins.&lt;/p&gt;
&lt;h2&gt;
  
  
  Le “Qui est-ce” des plateformes d’intégration continue
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E7NxAnha--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A9JsoC5uYjrBOfzY0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E7NxAnha--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2A9JsoC5uYjrBOfzY0" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Est-ce qu’il est roux ? Non ? Ok je retire Gitlab CI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Plus sérieusement, la première question à se poser est : &lt;strong&gt;quelles sont les technologies que la plateforme doit supporter ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rien de mieux qu’un bon vieux tableau comparatif pour représenter ça 🎯&lt;/p&gt;

&lt;p&gt;⏩ Nous avons testé pour vous l’ensemble des plateformes, mais dans un soucis de temps de lecture nous allons passer directement aux conclusions ⏩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tch73F4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4068/1%2AP-v4IOMbOTcECqRX5zIaLg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tch73F4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/4068/1%2AP-v4IOMbOTcECqRX5zIaLg.png" alt="Tableau de compatibilité Technologie / Plateforme"&gt;&lt;/a&gt;&lt;em&gt;Tableau de compatibilité Technologie / Plateforme&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;⛔ Suite à notre analyse et comme le montre bien le tableau ci-dessus, il ressort d’emblée que &lt;em&gt;TeamCity&lt;/em&gt; et &lt;em&gt;Codeship&lt;/em&gt; ne sont pas du tout adaptés au monde du Mobile.&lt;/p&gt;

&lt;p&gt;Ensuite, en considérant nos 4 critères de départ, plus le titre de cet article, on peut également dire que les plateformes &lt;strong&gt;On-Premise&lt;/strong&gt; ne nous semblent pas adaptées. Non pas qu’elles ne soient pas performantes bien au contraire, nous en avons mises en place chez de nombreux clients et continuons à les utiliser, mais à moins que vous n’ayez un plateau de 20 développeurs, des budgets importants et des équipes dédiées à leur mise en place/administration/maintenance je ne pense pas que ces solutions soient faites pour vous (si c’est votre cas &lt;a href="https://www.bewizyu.com/contact"&gt;contactez-nous&lt;/a&gt;, on peut vous aider!).&lt;/p&gt;

&lt;p&gt;Les &lt;strong&gt;plus&lt;/strong&gt; 👍 du &lt;strong&gt;On-Premise&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Comme leurs noms l’indique elles sont &lt;strong&gt;“On-Premise”&lt;/strong&gt; ce qui par définition veut dire que vous pouvez les faire tourner directement chez vous. On retrouve souvent ce genre de besoin lorsqu’on a des problématiques de sécurité et de confidentialité des données (banque, assurance, etc…).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Les 3 plateformes offrent une architecture master/slave qui permet de scaler votre infra et de monter en charge facilement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Et enfin ces outils sont plus des &lt;strong&gt;Orchestrateurs&lt;/strong&gt; que des plateformes de CI/CD donc pas directement liés à des langages ou à des outils. Ils disposent d’une grande communauté et proposent des adapteurs/plugins pour la plus part des outils dont vous pourriez avoir besoin, vous ne devriez donc pas être bridés dans leur utilisation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les &lt;strong&gt;moins&lt;/strong&gt; 👎 :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;La gestion de l’infrastructure est à votre charge, même si c’est un aspect positif pour certains cela représente un coût important autant en matériel qu’en ressources humaines. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Le fait de devoir gérer des applications iOS par exemple nécessite du matériel qui coûte cher. D’expérience un &lt;a href="https://www.apple.com/fr/shop/buy-mac/mac-mini"&gt;Mac Mini&lt;/a&gt; est rarement suffisant donc il vous faudra regarder du côté des &lt;a href="https://www.apple.com/fr/shop/buy-mac/mac-pro"&gt;Mac Pro&lt;/a&gt; : ticket d’entrée 3 300€ minimum&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;En terme de Run ça vous fait un outil de plus à faire tourner et à administrer, ce qui entraine également des problèmes de gouvernance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Spécificité de Gitlab CI, vous restez dans l’univers Gitlab, impossible de connecter une autre source de code (comme Github ou BitBucket par exemple)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pour finir notre &lt;strong&gt;“Qui est-ce?”&lt;/strong&gt;, Travis CI et Circle CI étant très similaires dans leur approche nous n’allons conserver que Travis CI pour la catégorie des outils &lt;strong&gt;Modulaires&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Bitrise, App Center et Travis CI sont donc les finalistes pour notre Benchmark !
&lt;/h1&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Benchmark : Le Podium final
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3xCEIcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AXPNGkDsu1Kgn_BpVaGslCg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y3xCEIcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AXPNGkDsu1Kgn_BpVaGslCg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On a fait 80% du boulot en répondant aux questions précédentes maintenant, comme le veut la &lt;a href="https://fr.wikipedia.org/wiki/Principe_de_Pareto"&gt;loi de Pareto&lt;/a&gt;, les ennuis commencent ! Pour simplifier je vous ai mis à disposition un repo Android pour faire un cas concret d’utilisation.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/RBonaventure"&gt;
        RBonaventure
      &lt;/a&gt; / &lt;a href="https://github.com/RBonaventure/pot-pourri-android"&gt;
        pot-pourri-android
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Expérimentations autour des bétas de Firebase.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Firebase Sample Project &lt;a href="https://app.bitrise.io/app/2f1629da6bc411f3" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/964805a83b0d34416ab793c869a5bc494e0601b46722c696daba048e12fb9540/68747470733a2f2f6170702e626974726973652e696f2f6170702f326631363239646136626334313166332f7374617475732e7376673f746f6b656e3d5758715632624869684b47386545354568414c716d77266272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://travis-ci.org/RBonaventure/pot-pourri-android" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/4ed2619cbb22d77c70f6005c7ad669694063614ba74c868f5962f992408d8ec8/68747470733a2f2f7472617669732d63692e6f72672f52426f6e6176656e747572652f706f742d706f757272692d616e64726f69642e7376673f6272616e63683d6d6173746572" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://www.codacy.com/app/RBonaventure/pot-pourri-android?utm_source=github.com&amp;amp;utm_medium=referral&amp;amp;utm_content=RBonaventure/pot-pourri-android&amp;amp;utm_campaign=Badge_Grade" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/3919ae2a50a748e7a3483e6c662ce8e7babf64e0e40e83e065136e352e9e286b/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f6564636635386234333464643462353439636262376130373431613935653238" alt="Codacy Badge"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;Auteur : Raphaël Bonaventure&lt;/p&gt;

&lt;p&gt;Quelques exemples d'intégration d'outils Firebase pour Android.&lt;/p&gt;
&lt;p&gt;⚠️ Si vous voulez compiler cet exemple il vous faudra un projet Firebase et son fichier de configuration, comme décrit sur le &lt;a href="https://github.com/firebase/quickstart-android/blob/master/README.md"&gt;Github officiel&lt;/a&gt;
Les exemples de page HelloWorld sont dans le dossier "web/public".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@raph.bonaventure" rel="nofollow"&gt;Posts Medium faisant référence à ce repo&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
License&lt;/h2&gt;
&lt;p&gt;Copyright 2017 Raphaël Bonaventure&lt;/p&gt;
&lt;p&gt;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:&lt;/p&gt;
&lt;p&gt;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&lt;/p&gt;
&lt;p&gt;THE SOFTWARE IS…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/RBonaventure/pot-pourri-android"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Pour départager nos finalistes on a isolé 5 critères :&lt;/p&gt;

&lt;p&gt;⚡ Plug &amp;amp; Play (Facilité de mise en place / d’utilisation / de maintenance)&lt;/p&gt;

&lt;p&gt;🚀 Performances (scalabilité / vitesse d’execution / temps de build)&lt;/p&gt;

&lt;p&gt;🔗 Interconnection avec vos outils préférés (Github/Gitlab/BitBucket, Slack, SonarQube, App Stores, etc…)&lt;/p&gt;

&lt;p&gt;💬 Communauté (support / documentation / open-source)&lt;/p&gt;

&lt;p&gt;💰 Prix (of course)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DVd-W4T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AWo960igzwChzq_wCG-Nc_A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DVd-W4T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AWo960igzwChzq_wCG-Nc_A.png" alt="Exemple : [https://app.bitrise.io/build/71dd94d903a7ee97#?tab=log](https://app.bitrise.io/build/71dd94d903a7ee97#?tab=log)"&gt;&lt;/a&gt;&lt;em&gt;Exemple : &lt;a href="https://app.bitrise.io/build/71dd94d903a7ee97#?tab=log"&gt;https://app.bitrise.io/build/71dd94d903a7ee97#?tab=log&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UKRleYWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ApDAsWm979ia4GbyOjc53Lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UKRleYWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ApDAsWm979ia4GbyOjc53Lg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plug &amp;amp; Play : L’interface web a quelques loupés mais ils proposent : détection automatique de la techno, stack customizable, interface de création de workflow en mode WYSIWYG, c’est top !&lt;/p&gt;

&lt;p&gt;Performances : Temps de up des VM assez long, plus y’a de steps dans vos workflows plus c’est lent. C’est pas son point fort !&lt;/p&gt;

&lt;p&gt;Interconnection : &lt;a href="https://www.bitrise.io/integrations/steps"&gt;180+ intégrations&lt;/a&gt; open-source ! Possibilité d’écrire soit même ses scripts, les possibilités sont infinis !&lt;/p&gt;

&lt;p&gt;Communauté : La communauté est grandissante et le support via le Chat est génial. Ils vont jusqu’à debugguer ton App ;-)&lt;/p&gt;

&lt;p&gt;Prix : Premier prix : Free limité à 10mins de build, ensuite c’est fonction de la puissance des machines et du nombre de builds concurrents que vous voulez. Plus vous avez d’apps plus c’est salé ! Avec 100€/mois on commence vraiment à jouer&lt;br&gt;
&lt;a href="https://www.bitrise.io/pricing/teams"&gt;&lt;strong&gt;Bitrise - Pricing&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Android, iOS &amp;amp; cross-platform mobile continuous integration / delivery, with 200+ integrations. Sign up and start…&lt;/em&gt; www.bitrise.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--16xf7ZHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ATkFO-J2CO8K5gEanO6ht0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--16xf7ZHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ATkFO-J2CO8K5gEanO6ht0g.png" alt="Exemple : Impossible de faire des pages publiques… DM pour que je vous ajoute sur ma Team ;-)"&gt;&lt;/a&gt;&lt;em&gt;Exemple : Impossible de faire des pages publiques… DM pour que je vous ajoute sur ma Team ;-)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--78Bc3O4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ACi693fDcLL8y5IH7WHapkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--78Bc3O4g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2ACi693fDcLL8y5IH7WHapkg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plug &amp;amp; Play : l’intégration est assez simple par contre on ne peut quasiment rien customizer. Il faut que vos App soient standards de chez standards.&lt;/p&gt;

&lt;p&gt;Performances : 3mins pour le build Android, c’est le grand gagnant, par contre on ne sait pas sur quelles machines tournent les builds. Impossible de choisir la stack d’execution à date (cf &lt;a href="https://github.com/Microsoft/appcenter/wiki/Roadmap"&gt;Roadmap&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Interconnection : Microsoft Teams, Slack, et c’est tout 🙀&lt;/p&gt;

&lt;p&gt;Communauté : le produit est assez peu utilisé et il n’existe pas de support à part des &lt;a href="https://github.com/Microsoft/appcenter/issues"&gt;Github issues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prix : Gratuit dans la limite de 240mins de build/mois puis 40$/concurrence&lt;br&gt;
&lt;a href="https://visualstudio.microsoft.com/app-center/pricing/"&gt;&lt;strong&gt;Visual Studio App Center Pricing | Visual Studio&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;We've made App Center available for all Our generous free tier enables you to ship 5-star, higher-quality iOS, Android…&lt;/em&gt; visualstudio.microsoft.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x--HrxtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AAZaDKb_TleapHnePTRGSvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x--HrxtY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2AAZaDKb_TleapHnePTRGSvw.png" alt="Exemple : [https://travis-ci.org/RBonaventure/pot-pourri-android/builds/560017254](https://travis-ci.org/RBonaventure/pot-pourri-android/builds/560017254)"&gt;&lt;/a&gt;&lt;em&gt;Exemple : &lt;a href="https://travis-ci.org/RBonaventure/pot-pourri-android/builds/560017254"&gt;https://travis-ci.org/RBonaventure/pot-pourri-android/builds/560017254&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gwbH_mTv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Alu-EWMeHoI2odHXrbvi7kA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gwbH_mTv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2Alu-EWMeHoI2odHXrbvi7kA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plug &amp;amp; Play : Des stacks dédiées au mobile existent et la plupart des paramètres spécifiques sont customizables. Très flexible mais pas vraiment simple à mettre en place dès qu’on veut faire des choses un peu avancées (publication sur les stores par exemple). YAML de mon POC &lt;a href="https://gist.github.com/RBonaventure/af12593742ef5a38c1e9aa38d13cb58b"&gt;ici&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Performances : 4mins de build. Plutôt bien. Possibilité de fournir ses propres images Docker pour les Builds. Possibilité de jouer des jobs en parallèle. Même si l&lt;a href="https://docs.travis-ci.com/user/reference/overview/#virtualisation-environment-vs-operating-system"&gt;es VM peuvent être un peu longue à boot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Interconnection : &lt;a href="https://docs.travis-ci.com/user/apps/"&gt;Une liste d’add-ons&lt;/a&gt; est proposée mais à part SonarCloud je n’ai pas trouvé grand chose d’intéressant…&lt;/p&gt;

&lt;p&gt;Communauté : Il existe un forum dans lequel vous pouvez créer des tickets de demande d’aide mais ça ne va pas plus loin !&lt;/p&gt;

&lt;p&gt;Prix : Gratuit pour les projets Open-Source ! Sinon toujours le même principe de builds concurrents. Premier pix 69$/mois.&lt;br&gt;
&lt;a href="https://travis-ci.com/plans"&gt;&lt;strong&gt;Travis CI - Pricing&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Edit description&lt;/em&gt; travis-ci.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Comment bien choisir sa CI/CD Mobile en 2019 ?&lt;/p&gt;

&lt;p&gt;La première réponse : Ce n’est pas à moi de vous dire quelle solution choisir.&lt;/p&gt;

&lt;p&gt;La réponse de Normand : Ça dépend de vos besoins et de vos moyens.&lt;/p&gt;

&lt;p&gt;La réponse terre à terre : pour un contrôle total de votre outil préférez Jenkins (ou Gitlab CI si votre entreprise utilise déjà Gitlab). Si vous voulez mutualiser votre CI avec du Web ou du Back un outil comme TravisCI ou CircleCI répondra surement à la plupart de vos besoins. Et enfin si vous voulez juste appuyer sur des boutons et utiliser des connecteurs tout faits mieux vaut partir sur Bitrise, ou App Center si vous êtes déjà chez Microsoft !&lt;/p&gt;

&lt;p&gt;La réponse D : personnellement je ne peux plus me passer de la fléxibilité de Bitrise ! De plus ils connaissent une forte croissance et un taux d’adoption énorme sur les plus gros plateaux de Dév mobile et viennent &lt;a href="https://blog.bitrise.io/series-b-funding"&gt;de lever 20M&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Besoin d’un accompagnement sur mesure, faites appel à nous !&lt;/em&gt;&lt;br&gt;
&lt;a href="https://bewizyu.com/make/digital-factory/application-mobile/"&gt;&lt;strong&gt;BEWIZYU&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Développement, expertise sur plateformes à usage mobile&lt;/em&gt; www.bewizyu.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ci</category>
      <category>devops</category>
      <category>android</category>
    </item>
    <item>
      <title>In App Purchase with Ionic / Cordova</title>
      <dc:creator>Hamza Hsain</dc:creator>
      <pubDate>Mon, 22 Jul 2019 15:43:16 +0000</pubDate>
      <link>https://dev.to/bewizyu/in-app-purchase-with-ionic-cordova-3fjc</link>
      <guid>https://dev.to/bewizyu/in-app-purchase-with-ionic-cordova-3fjc</guid>
      <description>&lt;p&gt;Article initialement posté sur &lt;a href="https://medium.com/bewizyu/in-app-purchase-with-ionic-cordova-18960239f989" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In App Purchase (or integrated purchase) gives the opportunity to sell additional content within a native mobile application (smartphone and tablet). If your product matches the in-app purchase categories bellow, then you can, and even must, use In app-purchase.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3044%2F1%2AA7DWo3FqQqnAuJiXNVQrGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3044%2F1%2AA7DWo3FqQqnAuJiXNVQrGg.png" alt="A typical example of IAP"&gt;&lt;/a&gt;&lt;em&gt;A typical example of IAP&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What can I sell using IAP ?
&lt;/h2&gt;

&lt;p&gt;In principle, you can sell whatever you want as long as it belongs to the following categories :&lt;/p&gt;

&lt;h3&gt;
  
  
  Consumable
&lt;/h3&gt;

&lt;p&gt;Users can purchase different types of consumables, such as lives or gems in a game, to further their progress through an app. Consumable in-app purchases are used once, are depleted, and can be purchased again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Consumable
&lt;/h3&gt;

&lt;p&gt;Users can purchase non-consumable, premium features within an app. Non-consumables are purchased once and do not expire, such as additional filters in a photo app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto-Renewable Subscriptions
&lt;/h3&gt;

&lt;p&gt;Users can purchase access to services or periodically updated content, such as monthly access to cloud storage or a weekly subscription to a magazine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Non-Renewing Subscriptions
&lt;/h3&gt;

&lt;p&gt;Users can purchase access to services or content for a limited duration, such as a season pass to streaming content. This type of subscription does not renew automatically, so users need to renew each time.&lt;/p&gt;

&lt;p&gt;You can find more informations here =&amp;gt; &lt;a href="https://developer.apple.com/in-app-purchase/" rel="noopener noreferrer"&gt;the apple documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Bewiz Spin App
&lt;/h2&gt;

&lt;p&gt;We want to create a mobile app in which the user can buy credits that we will call &lt;strong&gt;Bewiz.&lt;/strong&gt; With these Bewizs he can spin a wheel, to try to win gifts 🎁 (1 Bewiz =&amp;gt; 1 spin)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F9216%2F1%2AF8D_fSLWaMv0vszCw9Ytbg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F9216%2F1%2AF8D_fSLWaMv0vszCw9Ytbg.jpeg" alt="Photo by [Navneet Shanu ](https://www.pexels.com/@navneet-shanu-202773?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels)from [Pexels](https://www.pexels.com/photo/brown-carriage-wheel-672630/?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels)"&gt;&lt;/a&gt;&lt;em&gt;Photo by &lt;a href="https://www.pexels.com/@navneet-shanu-202773?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels" rel="noopener noreferrer"&gt;Navneet Shanu &lt;/a&gt;from &lt;a href="https://www.pexels.com/photo/brown-carriage-wheel-672630/?utm_content=attributionCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=pexels" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For our case, we will need to use consumable products because it's used to buy credits that are used once to spin the wheel.&lt;/p&gt;

&lt;p&gt;Lets imagine that we have this set of suggested products :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2358%2F1%2AN2ah_00DHtC_Spp_yapd0Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2358%2F1%2AN2ah_00DHtC_Spp_yapd0Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; Bewiz for &lt;strong&gt;10€&lt;/strong&gt;, &lt;strong&gt;50&lt;/strong&gt; Bewiz for &lt;strong&gt;40€&lt;/strong&gt; and &lt;strong&gt;100&lt;/strong&gt; Bewiz for &lt;strong&gt;75€&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's see how can we put all this in place … 😀&lt;/p&gt;

&lt;h2&gt;
  
  
  What I need to set up IAP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ionic / Cordova mobile application
&lt;/h3&gt;

&lt;p&gt;As we will develop an ionic mobile app, you can follow these steps to initiate your project :&lt;br&gt;
&lt;a href="https://ionicframework.com/getting-started#cli" rel="noopener noreferrer"&gt;&lt;strong&gt;Free Mobile App Development: Getting Started with Ionic Apps&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Create an Ionic App using one of our ready-made app templates, or a blank one to start fresh. Check out the Market for…&lt;/em&gt; ionicframework.com&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Server side application
&lt;/h3&gt;

&lt;p&gt;For security reasons, the purchase validation should be done in the server side.&lt;/p&gt;

&lt;p&gt;After each purchase the store returns a receipt data that should be validated in the server side (a base64 string for IOS, and a Json format for Android).&lt;/p&gt;

&lt;p&gt;For our Bewiz Spin we will use a PHP server side receipt validation using this open source library :&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/aporat" rel="noopener noreferrer"&gt;
        aporat
      &lt;/a&gt; / &lt;a href="https://github.com/aporat/store-receipt-validator" rel="noopener noreferrer"&gt;
        store-receipt-validator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      PHP receipt validator for Apple iTunes, Google Play and Amazon App Store
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;store-receipt-validator&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://packagist.org/packages/aporat/store-receipt-validator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6db935b196336db3eec0f9ee2a8d7b0298cb762b6c133ba77690c234e411c2d8/68747470733a2f2f706f7365722e707567782e6f72672f61706f7261742f73746f72652d726563656970742d76616c696461746f722f76657273696f6e2e706e67" alt="Latest Stable Version"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/aporat/store-receipt-validator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/581ec107dff51ed15da1ede3a97e529c869bb4efa9849bfa1ae26737e6564f45/68747470733a2f2f706f7365722e707567782e6f72672f61706f7261742f73746f72652d726563656970742d76616c696461746f722f642f746f74616c2e706e67" alt="Composer Downloads"&gt;&lt;/a&gt;
&lt;a href="https://github.com/aporat/store-receipt-validator/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/aporat/store-receipt-validator/workflows/Tests/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://scrutinizer-ci.com/g/aporat/store-receipt-validator/?branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ccec1f3c432b04da3344a2a952a386c9ad680ae604c5ebfefabb6fea00817d22/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f61706f7261742f73746f72652d726563656970742d76616c696461746f722f6261646765732f636f7665726167652e706e673f623d6d6173746572" alt="Code Coverage"&gt;&lt;/a&gt;
&lt;a href="https://scrutinizer-ci.com/g/aporat/store-receipt-validator/?branch=master" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6eb1512a78530c5f4312fa6f4e212ebf2a0b27a3cf29d35a28ececdcd9801e2f/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f61706f7261742f73746f72652d726563656970742d76616c696461746f722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572" alt="Scrutinizer Code Quality"&gt;&lt;/a&gt;
&lt;a href="https://github.styleci.io/repos/14928361" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8824d10fde368e41430b5d8393856a25821f084c4df0e8168fc4afa9c11d684b/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f31343932383336312f736869656c643f6272616e63683d6d6173746572" alt="StyleCI"&gt;&lt;/a&gt;
&lt;a href="https://packagist.org/packages/aporat/store-receipt-validator" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eb33db76a23777c408916510f76a9225f594469b532bba45ed6ef0c5b7109ce2/68747470733a2f2f706f7365722e707567782e6f72672f61706f7261742f73746f72652d726563656970742d76616c696461746f722f6c6963656e73652e737667" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PHP receipt validator for Apple iTunes, Google Play and Amazon App Store&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;PHP &amp;gt;= 7.3&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;composer require aporat/store-receipt-validator&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Example&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;iTunes&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-text-html-php notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;use&lt;/span&gt; &lt;span class="pl-v"&gt;ReceiptValidator&lt;/span&gt;\iTunes\&lt;span class="pl-v"&gt;Validator&lt;/span&gt; &lt;span class="pl-k"&gt;as&lt;/span&gt; iTunesValidator
&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;validator&lt;/span&gt; = &lt;span class="pl-k"&gt;new&lt;/span&gt; iTunesValidator(iTunesValidator::&lt;span class="pl-c1"&gt;ENDPOINT_PRODUCTION&lt;/span&gt;); &lt;span class="pl-c"&gt;// Or iTunesValidator::ENDPOINT_SANDBOX if sandbox testing&lt;/span&gt;

&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;receiptBase64Data&lt;/span&gt; = &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;ewoJInNpZ25hdHVyZSIgPSAiQXBNVUJDODZBbHpOaWtWNVl0clpBTWlKUWJLOEVkZVhrNjNrV0JBWHpsQzhkWEd1anE0N1puSVlLb0ZFMW9OL0ZTOGNYbEZmcDlZWHQ5aU1CZEwyNTBsUlJtaU5HYnloaXRyeVlWQVFvcmkzMlc5YVIwVDhML2FZVkJkZlcrT3kvUXlQWkVtb05LeGhudDJXTlNVRG9VaFo4Wis0cFA3MHBlNWtVUWxiZElWaEFBQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NHVVVrVTNaV0FTMU1BMEdDU3FHU0liM0RRRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIzSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEE1TURZeE5USXlNRFUxTmxvWERURTBNRFl4TkRJeU1EVTFObG93WkRFak1DRUdBMVVFQXd3YVVIVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVrRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFNclJqRjJjdDRJclNkaVRDaGFJMGc4cHd2L2NtSHM4cC9Sd1YvcnQvOTFYS1ZoTmw0WElCaW1LalFRTmZnSHNEczZ5anUrK0RyS0pFN3VLc3BoTWRkS1lmRkU1ckdYc0FkQkVqQndSSXhleFRldngzSExFRkdBdDFtb0t4NTA5ZGh4dGlJZERnSnYyWWFWczQ5QjB1SnZOZHk2U01xTk5MSHNETHpEUzlvWkhBZ01CQUFHamNqQndNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqQkJnd0ZvQVVOaDNvNHAyQzBnRVl0VEpyRHRkREM1RllRem93RGdZRFZSMFBBUUgvQkFRREFnZUFNQjBHQTFVZERnUVdCQlNwZzRQeUdVakZQaEpYQ0JUTXphTittVjhrOVRBUUJnb3Foa2lHOTJOa0JnVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUVhU2JQanRtTjRDL0lCM1FFcEszMlJ4YWNDRFhkVlhBZVZSZVM1RmFaeGMrdDg4cFFQOTNCaUF4dmRXLzNlVFNNR1k1RmJlQVlMM2V0cVA1Z204d3JGb2pYMGlreVZSU3RRKy9BUTBLRWp0cUIwN2tMczlRVWU4Y3pSOFVHZmRNMUV1bVYvVWd2RGQ0TndOWXhMUU1nNFdUUWZna1FRVnk4R1had1ZIZ2JFL1VDNlk3MDUzcEdYQms1MU5QTTN3b3hoZDNnU1JMdlhqK2xvSHNTdGNURXFlOXBCRHBtRzUrc2s0dHcrR0szR01lRU41LytlMVFUOW5wL0tsMW5qK2FCdzdDMHhzeTBiRm5hQWQxY1NTNnhkb3J5L0NVdk02Z3RLc21uT09kcVRlc2JwMGJzOHNuNldxczBDOWRnY3hSSHVPTVoydG04bnBMVW03YXJnT1N6UT09IjsKCSJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdSaGRHVXRjSE4wSWlBOUlDSXlNREV5TFRBMExUTXdJREE0T2pBMU9qVTFJRUZ0WlhKcFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkltOXlhV2RwYm1Gc0xYUnlZVzV6WVdOMGFXOXVMV2xrSWlBOUlDSXhNREF3TURBd01EUTJNVGM0T0RFM0lqc0tDU0ppZG5KeklpQTlJQ0l5TURFeU1EUXlOeUk3Q2draWRISmhibk5oWTNScGIyNHRhV1FpSUQwZ0lqRXdNREF3TURBd05EWXhOemc0TVRjaU93b0pJbkYxWVc1MGFYUjVJaUE5SUNJeElqc0tDU0p2Y21sbmFXNWhiQzF3ZFhKamFHRnpaUzFrWVhSbExXMXpJaUE5SUNJeE16TTFOems0TXpVMU9EWTRJanNLQ1NKd2NtOWtkV04wTFdsa0lpQTlJQ0pqYjIwdWJXbHVaRzF2WW1Gd2NDNWtiM2R1Ykc5aFpDSTdDZ2tpYVhSbGJTMXBaQ0lnUFNBaU5USXhNVEk1T0RFeUlqc0tDU0ppYVdRaUlEMGdJbU52YlM1dGFXNWtiVzlpWVhCd0xrMXBibVJOYjJJaU93b0pJbkIxY21Ob1lYTmxMV1JoZEdVdGJYTWlJRDBnSWpFek16VTNPVGd6TlRVNE5qZ2lPd29KSW5CMWNtTm9ZWE5sTFdSaGRHVWlJRDBnSWpJd01USXRNRFF0TXpBZ01UVTZNRFU2TlRVZ1JYUmpMMGROVkNJN0Nna2ljSFZ5WTJoaGMyVXRaR0YwWlMxd2MzUWlJRDBnSWpJd01USXRNRFF0TXpBZ01EZzZNRFU2TlRVZ1FXMWxjbWxqWVM5TWIzTmZRVzVuWld4bGN5STdDZ2tpYjNKcFoybHVZV3d0Y0hWeVkyaGhjMlV0WkdGMFpTSWdQU0FpTWpBeE1pMHdOQzB6TUNBeE5Ub3dOVG8xTlNCRmRHTXZSMDFVSWpzS2ZRPT0iOwoJImVudmlyb25tZW50IiA9ICJTYW5kYm94IjsKCSJwb2QiID0gIjEwMCI7Cgkic2lnbmluZy1zdGF0dXMiID0gIjAiOwp9&lt;/span&gt;'&lt;/span&gt;;

&lt;span class="pl-k"&gt;try&lt;/span&gt; {
  &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;response&lt;/span&gt; = &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;validator&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;setReceiptData&lt;/span&gt;(&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;receiptBase64Data&lt;/span&gt;)-&amp;gt;&lt;span class="pl-en"&gt;validate&lt;/span&gt;();
  &lt;span class="pl-c"&gt;// $sharedSecret = '1234...'; // Generated in iTunes Connect's In-App Purchase menu&lt;/span&gt;
  &lt;span class="pl-c"&gt;// $response = $validator-&amp;gt;setSharedSecret($sharedSecret)-&amp;gt;setReceiptData($receiptBase64Data)-&amp;gt;validate(); // use setSharedSecret() if for recurring subscriptions&lt;/span&gt;
} &lt;span class="pl-k"&gt;catch&lt;/span&gt; (&lt;span class="pl-smi"&gt;&lt;span class="pl-smi"&gt;Exception&lt;/span&gt;&lt;/span&gt; &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;e&lt;/span&gt;) {
  &lt;span class="pl-k"&gt;echo&lt;/span&gt; &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;got error = &lt;/span&gt;'&lt;/span&gt; . &lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;e&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;getMessage&lt;/span&gt;() . &lt;span class="pl-c1"&gt;PHP_EOL&lt;/span&gt;;
}

&lt;span class="pl-k"&gt;if&lt;/span&gt; (&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;response&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;isValid&lt;/span&gt;()) {
  &lt;span class="pl-k"&gt;echo&lt;/span&gt; &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;Receipt is valid.&lt;/span&gt;'&lt;/span&gt; . &lt;span class="pl-c1"&gt;PHP_EOL&lt;/span&gt;;
  &lt;span class="pl-k"&gt;echo&lt;/span&gt; &lt;span class="pl-s"&gt;'&lt;span class="pl-s"&gt;Receipt data = &lt;/span&gt;'&lt;/span&gt; . &lt;span class="pl-en"&gt;print_r&lt;/span&gt;(&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;response&lt;/span&gt;-&amp;gt;&lt;span class="pl-en"&gt;getReceipt&lt;/span&gt;()) . &lt;span class="pl-c1"&gt;PHP_EOL&lt;/span&gt;;
  
  &lt;span class="pl-k"&gt;foreach&lt;/span&gt; (&lt;span class="pl-s1"&gt;&lt;span class="pl-c1"&gt;$&lt;/span&gt;response&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/aporat/store-receipt-validator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  In app purchase Cordova plugin
&lt;/h3&gt;

&lt;p&gt;For now, there is one main open source cordova plugin available on Github and supported by the ionic community.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/j3k0" rel="noopener noreferrer"&gt;
        j3k0
      &lt;/a&gt; / &lt;a href="https://github.com/j3k0/cordova-plugin-purchase" rel="noopener noreferrer"&gt;
        cordova-plugin-purchase
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      In-App Purchase for Cordova on iOS, Android and Windows
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Cordova Purchase Plugin&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;In-App Purchases for Cordova&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Need professional help and support? &lt;a href="https://github.com/j3k0/cordova-plugin-purchasemailto:hoelt@fovea.cc" rel="noopener noreferrer"&gt;Contact Me&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Summary&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;This plugin allows &lt;strong&gt;In-App Purchases&lt;/strong&gt; to be made from &lt;strong&gt;Cordova, Ionic and Capacitor&lt;/strong&gt; applications.&lt;/p&gt;
&lt;p&gt;It lets you handle in-app purchases on many platforms with a single codebase.&lt;/p&gt;
&lt;p&gt;This is a plugin for the &lt;strong&gt;Apache Cordova&lt;/strong&gt; framework that provides an easy and flexible way to integrate &lt;strong&gt;in-app purchases&lt;/strong&gt; into Cordova-based mobile applications, including popular frameworks such as &lt;strong&gt;Ionic and PhoneGap&lt;/strong&gt;. With this plugin, you can easily add support for in-app purchases of digital content, such as subscriptions, consumables, and non-consumables, using the store-specific purchase APIs provided by the major mobile platforms. The plugin also supports requesting payments through popular payment providers such as &lt;strong&gt;Braintree&lt;/strong&gt;, allowing you to easily accept payments from your users.&lt;/p&gt;
&lt;p&gt;The Cordova-Plugin-Purchase plugin is designed to be easy to use and integrate into your Cordova app, and it provides a…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/j3k0/cordova-plugin-purchase" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;There is also a wrapper for ionic applications :&lt;br&gt;
&lt;a href="https://ionicframework.com/docs/native/in-app-purchase-2" rel="noopener noreferrer"&gt;&lt;strong&gt;In App Purchase 2 - Ionic Documentation&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Ionic is the app platform for web developers. Build amazing mobile, web, and desktop apps all with one shared code base…&lt;/em&gt; ionicframework.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add all these dependencies to your &lt;strong&gt;package.json&lt;/strong&gt; :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;BILLING_KEY in the plugin's configuration matches your license key for in-app billing should be added manually to your project. This key is found in Services and API in the Google Play Developer Console.&lt;br&gt;
For more informations : &lt;a href="https://github.com/j3k0/cordova-plugin-purchase/wiki/Setup-for-Android-Google-Play#add-android-billing-key" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Google and Apple accounts
&lt;/h3&gt;

&lt;p&gt;To be able to configure your IAP items you need to create an iTunes developer account for IOS app and play store account for Android&lt;br&gt;
&lt;a href="https://developer.apple.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Apple Developer&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;There's never been a better time to develop for Apple Platforms.&lt;/em&gt; developer.apple.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.android.com/distribute/console" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Play Console&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Publish your apps and games with the Google Play Console and grow your business on Google Play. Benefit from features…&lt;/em&gt; developer.android.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Register your products
&lt;/h2&gt;

&lt;p&gt;Register all your products in the google play console and apple iTunes console.&lt;/p&gt;

&lt;p&gt;For reminder, you have 3 products (10, 50 and 100 credits), so you have to create 3 product IDs: credits_10, credits_50, credits_100&lt;/p&gt;

&lt;p&gt;You can find below how to create your in app products on IOS and Android&lt;br&gt;
&lt;a href="https://support.pressmatrix.com/hc/en-us/articles/202331832-Create-In-App-Products-in-your-Google-Play-Account" rel="noopener noreferrer"&gt;&lt;strong&gt;Create In App Products in your Google Play Account&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;In order to be able to offer a fee-based edition through in-app purchases in your Kiosk-App for Android devices, an…&lt;/em&gt; support.pressmatrix.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.raywenderlich.com/5456-in-app-purchase-tutorial-getting-started" rel="noopener noreferrer"&gt;&lt;strong&gt;In-App Purchase Tutorial: Getting Started&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Learn how to grow app revenue in this in-app purchase tutorial by allowing users to purchase or unlock content or…&lt;/em&gt; www.raywenderlich.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the In App Products should be registered in the app bootstrap, this synchronize the local products data with the remote one.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  IAP Product lifecycle
&lt;/h2&gt;

&lt;p&gt;There is many events triggered with the purchase workflow, that allow us to handle and manage errors, success, updates …&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Approved&lt;/strong&gt; means that the product is purchased and the purchase is validated locally, ideally it's the best place to call product.verify() to start server side receipt validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cancelled&lt;/strong&gt; when the purchase is cancelled, it's time to show an error message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error&lt;/strong&gt; when an error occurs during purchase workflow&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated&lt;/strong&gt; it's a push based event, when the product informations are updated (price, label, … )&lt;/p&gt;

&lt;h2&gt;
  
  
  Server side verification
&lt;/h2&gt;

&lt;p&gt;When product.verify() is called, an inAppPurchase.validator event is triggered and it's the best place where you can execute your server side receipt verification.&lt;/p&gt;

&lt;p&gt;For our example the creditsProvider.purchase() is responsible for receipt verification and return a status according to the validation results ("success" or "failure")&lt;/p&gt;

&lt;p&gt;Having a success status means that the receipt is valid and now we can finish the transaction by calling product.finish()&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Execute IAP Order
&lt;/h2&gt;

&lt;p&gt;To trigger the purchase workflow above you should call the inAppPurchase.order()&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Turn off listeners
&lt;/h2&gt;

&lt;p&gt;After leaving the view, you should turn off all the event listeners by calling inAppPurchase.off()&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Sandbox and test users
&lt;/h2&gt;

&lt;p&gt;For testing purposes you should define sandbox iCloud users for IOS and add test users for Android.&lt;/p&gt;

&lt;p&gt;Here bellow you can find some links that will help&lt;/p&gt;

&lt;p&gt;Android&lt;br&gt;
&lt;a href="https://developer.android.com/google/play/billing/billing_testing" rel="noopener noreferrer"&gt;&lt;strong&gt;Test Google Play Billing | Android Developers&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;After you finish your static response testing, and you verify that signature verification is working in your…&lt;/em&gt; developer.android.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IOS&lt;br&gt;
&lt;a href="https://medium.com/@codeneophyte/how-to-create-a-sandbox-tester-account-on-itunes-connect-57eda4247f5c" rel="noopener noreferrer"&gt;&lt;strong&gt;How to create a Sandbox Tester Account on iTunes Connect&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Creating a Sandbox Tester account in easy thanks to iTunes Connect. A Sandbox account allows you, the developer, to…&lt;/em&gt; medium.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Finally a demo App…
&lt;/h2&gt;

&lt;p&gt;Now that you have all what you need to begin your IAP setup, you may probably wish to have a complete demo app with all the steps above… you can find bellow a complete demo app :&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/devHamza" rel="noopener noreferrer"&gt;
        devHamza
      &lt;/a&gt; / &lt;a href="https://github.com/devHamza/iap-demo-ionic-app" rel="noopener noreferrer"&gt;
        iap-demo-ionic-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo application for in app purchase with ionic / cordova
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="MD"&gt;
&lt;p&gt;This is a demo app for the article : "In App Purchase with Ionic/Cordova"
find more at &lt;a href="https://medium.com/bewizyu" rel="nofollow noopener noreferrer"&gt;https://medium.com/bewizyu&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/devHamza/iap-demo-ionic-app" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;&lt;a href="https://www.bewizyu.com/make" rel="noopener noreferrer"&gt;&lt;strong&gt;BEWIZYU Technology&lt;/strong&gt; &lt;em&gt;Développement, expertise sur plateformes à usage mobile&lt;/em&gt; www.bewizyu.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>ios</category>
      <category>cordova</category>
      <category>ionic</category>
    </item>
  </channel>
</rss>
