Docs

La bibliothèque

Cadrans et champs de données

Un cadran ne peut pas recevoir d'appuis sur les boutons ni accéder au réseau à l'écran. La bibliothèque interroge donc notre serveur en arrière-plan, votre cadran dessine le QR code où vous le choisissez, et la notification de connexion de Garmin permet à un acheteur de payer sans scanner. Les champs de données fonctionnent de la même façon.

Comment ça marche

  • L'arrière-plan interroge. Le service d'arrière-plan du cadran envoie à notre serveur la même requête qu'une application, à l'heure fixée par le serveur.
  • L'heure reste au premier plan. Sur un cadran, lire l'heure est une fonction principale, et Garmin déconseille tout paywall par-dessus. Tant qu'il est bloqué, votre cadran dessine le QR code où vous le choisissez. Un champ de données le dessine dans son propre espace.
  • Le lien est dans les paramètres. Le cadran écrit aussi son lien d'achat dans ses paramètres, que l'application Connect IQ du téléphone affiche. Un acheteur peut l'ouvrir là sans scanner.
  • La notification évite le scan. Une fois le cadran bloqué et le téléphone connecté, il envoie la notification de connexion de Garmin. L'acheteur la touche, paie, et le cadran se débloque en quelques secondes.

L'ajouter à un cadran ou un champ de données

Les cadrans et les champs de données utilisent seulement lib/watch/face : PayFace.mc et PayFaceScope.mc.

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/face
manifest.xml
<iq:permissions>
    <iq:uses-permission id="Background"/>
    <iq:uses-permission id="Communications"/>
</iq:permissions>

La config est annotée (:background), car l'arrière-plan la lit. Gardez-y TRIAL_DAYS, et réglez-le à 0 pour aucun essai : la partie cadran le lit directement.

source/PaywallConfig.mc
// PaywallConfig.mc: from your dashboard (Trail Face). Public, not a secret.
import Toybox.Lang;

(:background)
module PaywallConfig {
    const URL = "https://pay.example/api/K7Q2/c";   // your app's address
    const TRIAL_DAYS = 7;
}

Les points d'accroche

OùAppel
getInitialView()Paywall.startTrial(); Paywall.schedule(false); à chaque démarrage
getServiceDelegate()return [new PayBg()];
onBackgroundData(data)Paywall.take(data);
onSettingsChanged()Paywall.soon();
onUpdate(dc)if (!Paywall.unlocked()) { Paywall.drawQr(dc, x, y, side); }

Un cadran complet, avec l'heure en haut et le code dessous tant qu'il est bloqué :

source/PayFaceApp.mc
import Toybox.Application;
import Toybox.Background;
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.System;
import Toybox.Time;
import Toybox.WatchUi;

// A small face for measuring: the time, and the QR code under it while locked.
(:background)
class PayFaceApp extends Application.AppBase {
    function initialize() {
        AppBase.initialize();
    }

    function onStart(state as Dictionary or Null) as Void {
    }

    function getInitialView() {
        Paywall.startTrial();
        Paywall.schedule(false);
        return [new PayFaceView()];
    }

    function getServiceDelegate() {
        return [new PayBg()];
    }

    function onBackgroundData(data) as Void {
        Paywall.take(data);
    }

    // Saving the face's settings on the phone (the buy page suggests it after paying): ask now
    // (5 minutes after the last check at the soonest, Garmin's rule).
    function onSettingsChanged() as Void {
        Paywall.soon();
    }
}

class PayFaceView extends WatchUi.WatchFace {
    function initialize() {
        WatchFace.initialize();
    }

    function onUpdate(dc as Graphics.Dc) as Void {
        var w = dc.getWidth();
        var h = dc.getHeight();
        var t = System.getClockTime();
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        dc.clear();
        dc.drawText(w / 2, h * 30 / 100, Graphics.FONT_NUMBER_MEDIUM, t.hour.format("%02d") + ":" + t.min.format("%02d"),
            Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
        if (!Paywall.unlocked()) {
            Paywall.drawQr(dc, w / 2, h * 68 / 100, w * 36 / 100);
        }
    }
}

Ajoutez une propriété unlock en lecture seule. Le cadran la remplit avec le lien d'achat tiré de la réponse du serveur. Définissez la chaîne UnlockTitle dans vos propres ressources.

resources/settings/settings.xml
<resources>
    <!-- The buy link, written by the face from the server's answer: the phone's Connect IQ app
         shows it in this face's settings, so a buyer can open it without scanning. -->
    <properties>
        <property id="unlock" type="string"></property>
    </properties>
    <settings>
        <setting propertyKey="@Properties.unlock" title="@Strings.UnlockTitle">
            <settingConfig type="alphaNumeric" readonly="true"/>
        </setting>
    </settings>
</resources>

Dessiner le code

  • Paywall.drawQr(dc, x, y, side) dessine le code sur side de large, sur un carré blanc centré en x, y. Avant la première réponse, il ne dessine rien.
  • Appelez-la uniquement tant que !Paywall.unlocked().
  • Ne le dessinez qu'avec l'écran pleinement allumé, jamais en mode toujours activé d'une montre AMOLED.

La notification de connexion de Garmin

  • Quand elle est envoyée : une fois, la première fois qu'une vérification trouve le cadran bloqué (essai terminé, ou pas d'essai). À nouveau chaque fois que l'acheteur enregistre les paramètres du cadran pendant qu'il est bloqué. Seulement quand le téléphone est connecté : il faut le téléphone lui-même, pas le Wi-Fi.
  • Ce que voit l'acheteur : la notification de Garmin sur le téléphone. Garmin en rédige le texte (« <app> needs you to sign in »), et aucune application ne peut le changer. La toucher ouvre votre page de paiement dans le navigateur de Garmin Connect.
  • Après le paiement : la page se ferme, le téléphone transmet le résultat à la montre, et l'arrière-plan du cadran interroge notre serveur. Le résultat seul ne débloque rien, car n'importe qui pourrait saisir son adresse. Seule la réponse de notre serveur débloque.
  • Jamais envoyée deux fois par erreur : l'arrière-plan la marque lui-même comme envoyée (CIQ 3.2 et plus), même si le cadran ne s'exécute pas juste après. Sur une montre qui ne peut pas l'envoyer, le QR code et le lien des paramètres fonctionnent toujours.

Les applications ne l'envoient pas. L'écran d'achat d'une application se débloque déjà environ une seconde après le paiement.

Durée d'un déblocage

Notre serveur ne peut pas joindre une montre. Un cadran n'apprend un paiement qu'à sa prochaine vérification, et Garmin autorise une vérification en arrière-plan au plus toutes les 5 minutes.

Comment l'acheteur a payéLe cadran se débloque
A touché la notification de connexionEn quelques secondes
A scanné le code ou utilisé le lien des paramètres, dans les 2 jours après l'installation ou la fin de l'essaiEn moins de 10 minutes
La même chose, plus tardEn moins d'une heure
A enregistré les paramètres du cadran sur le téléphone après le paiementLors d'une vérification, dès que Garmin le permet : 5 minutes après la précédente au plus tôt
  • Dès qu'une vérification a vu la page de paiement ouverte, le cadran vérifie toutes les 5 minutes pendant une demi-heure.
  • Pendant l'essai, le cadran vérifie à la fin de l'essai, ou chaque jour si c'est plus tôt.
  • Après une vérification échouée (pas de téléphone), la suivante a lieu une heure plus tard.

Annotations et portée

Le code d'aperçu et d'arrière-plan n'atteint que le code annoté pour eux. Gardez les annotations de la bibliothèque telles quelles, et alignez les vôtres.

  • Cadrans et champs de données : PaywallConfig est (:background), tout comme votre classe AppBase, comme dans l'exemple : son getServiceDelegate() s'exécute en arrière-plan. PayBg et PayFaceScope.mc sont déjà annotés.
  • Applications avec un aperçu : glance/PayScope.mc et PaywallConfig sont (:glance). Un aperçu peut appeler Paywall.active(), Paywall.unlocked() et Paywall.trialLeft(), rien d'autre.
  • Applications avec leur propre service d'arrière-plan : glance-bg/PayScope.mc, PaywallConfig en (:glance, :background), et la permission Background.
  • Application seulement : tout ce qui est dans Pay.mc, y compris Paywall.open(), l'écran d'achat et ses textes. Ne l'appelez jamais depuis un aperçu ou du code d'arrière-plan.
Esc