A biblioteca
Mostradores e campos de dados
Um mostrador não recebe pressionamentos de botão nem acessa a rede na tela. Por isso a biblioteca consulta nosso servidor em segundo plano, seu mostrador desenha o QR code onde você escolher, e a notificação de login da Garmin permite ao comprador pagar sem escanear. Campos de dados funcionam do mesmo jeito.
Como funciona
- O segundo plano consulta. O serviço em segundo plano do mostrador envia ao nosso servidor a mesma requisição que um app envia, no horário que o servidor indicou.
- A hora fica por cima. Num mostrador, ver a hora é um recurso principal, e a Garmin recomenda não colocar paywall sobre ela. Enquanto bloqueado, seu mostrador desenha o QR code onde você escolher. Um campo de dados o desenha no próprio espaço.
- O link fica nas configurações. O mostrador também grava seu link de compra nas configurações, que o app Connect IQ do celular mostra. O comprador pode abri-lo ali sem escanear.
- A notificação dispensa o escaneamento. Quando o mostrador está bloqueado e o celular conectado, ele envia a notificação de login da Garmin. O comprador toca nela, paga, e o mostrador desbloqueia em segundos.
Adicione a um mostrador ou campo de dados
Mostradores e campos de dados usam só lib/watch/face: PayFace.mc e PayFaceScope.mc.
base.sourcePath = source;../wearcheckout/lib/watch/face<iq:permissions>
<iq:uses-permission id="Background"/>
<iq:uses-permission id="Communications"/>
</iq:permissions>A config é anotada com (:background), já que o segundo plano a lê. Mantenha TRIAL_DAYS nela, e defina como 0 para não ter teste: a parte do mostrador o lê diretamente.
// 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;
}Os hooks
| Onde | Chamada |
|---|---|
getInitialView() | Paywall.startTrial(); Paywall.schedule(false); a cada início |
getServiceDelegate() | return [new PayBg()]; |
onBackgroundData(data) | Paywall.take(data); |
onSettingsChanged() | Paywall.soon(); |
onUpdate(dc) | if (!Paywall.unlocked()) { Paywall.drawQr(dc, x, y, side); } |
Um mostrador completo, com a hora em cima e o código abaixo enquanto bloqueado:
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);
}
}
}O link nas configurações
Adicione uma propriedade unlock somente leitura. O mostrador a preenche com o link de compra da resposta do servidor. Defina a string UnlockTitle nos seus próprios recursos.
<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>Desenhar o código
Paywall.drawQr(dc, x, y, side)desenha o código comsidede largura num quadrado branco, centrado emx,y. Antes da primeira resposta, não desenha nada.- Chame só enquanto
!Paywall.unlocked(). - Desenhe só com a tela totalmente ligada, nunca no modo sempre ativo de um relógio AMOLED.
Notificação de login da Garmin
- Quando é enviada: uma vez, na primeira verificação que encontra o mostrador bloqueado (teste encerrado, ou sem teste). De novo cada vez que o comprador salva as configurações do mostrador enquanto ele está bloqueado. Só com o celular conectado: precisa do próprio celular, não do Wi-Fi.
- O que o comprador vê: a própria notificação da Garmin no celular. A Garmin escreve o texto ("<app> needs you to sign in"), e nenhum app pode mudá-lo. Tocar nela abre sua página de pagamento no navegador do próprio Garmin Connect.
- Depois do pagamento: a página termina, o celular passa o resultado ao relógio e o segundo plano do mostrador consulta nosso servidor. O resultado sozinho não desbloqueia nada, já que qualquer um poderia digitar o endereço. Só a resposta do nosso servidor desbloqueia.
- Nunca enviada duas vezes por engano: o próprio segundo plano a marca como enviada (CIQ 3.2 ou mais recente), mesmo que o mostrador não rode logo depois. Num relógio que não pode enviá-la, o QR code e o link das configurações continuam funcionando.
Apps não a enviam. A tela de compra de um app já desbloqueia cerca de um segundo após o pagamento.
Quanto tempo um desbloqueio leva
Nosso servidor não consegue alcançar um relógio. Um mostrador só fica sabendo de um pagamento na próxima verificação, e a Garmin permite uma verificação em segundo plano no máximo a cada 5 minutos.
| Como o comprador pagou | O mostrador desbloqueia |
|---|---|
| Tocou na notificação de login | Em segundos |
| Escaneou o código ou usou o link das configurações, nos 2 dias após a instalação ou o fim do teste | Em até 10 minutos |
| O mesmo, mais tarde | Em até uma hora |
| Salvou as configurações do mostrador no celular após pagar | Numa verificação assim que a Garmin permitir: no mínimo 5 minutos após a anterior |
- Quando uma verificação vê que o checkout foi aberto, o mostrador verifica a cada 5 minutos por meia hora.
- Durante o teste, o mostrador verifica no fim do teste, ou diariamente se isso vier antes.
- Após uma verificação com falha (sem celular), a próxima é uma hora depois.
Anotações e escopo
Código de glance e de segundo plano só alcança código anotado para eles. Mantenha as anotações da biblioteca como vêm e alinhe as suas.
- Mostradores e campos de dados:
PaywallConfigé(:background), e sua classeAppBasetambém, como no exemplo: ogetServiceDelegate()dela roda em segundo plano.PayBgePayFaceScope.mcjá estão anotados. - Apps com glance:
glance/PayScope.mcePaywallConfigsão(:glance). Um glance pode chamarPaywall.active(),Paywall.unlocked()ePaywall.trialLeft(), nada mais. - Apps com serviço próprio em segundo plano:
glance-bg/PayScope.mc,PaywallConfigcomo(:glance, :background)e a permissão Background. - Só no app: tudo em
Pay.mc, incluindoPaywall.open(), a tela de compra e suas strings. Nunca chame a partir de um glance ou de código em segundo plano.