Docs

A biblioteca

Adicione a biblioteca

A biblioteca desenha todas as telas de pagamento para você. Você adiciona as pastas dela, uma permissão, um pequeno arquivo de config e uma linha de código.

Os arquivos

Baixe a biblioteca na aba Instalar do seu app. Ela descompacta numa pasta wearcheckout.

CaminhoO que faz
lib/watch/app/Pay.mcApps: a verificação com nosso servidor, a tela de compra desenhada a partir da resposta do servidor, seu limite de tempo e o desbloqueio com som e vibração.
lib/watch/glance/PayScope.mcactive(), unlocked() e trialLeft(), com a anotação (:glance): para apps sem serviço em segundo plano.
lib/watch/glance-bg/PayScope.mcO mesmo, com a anotação (:glance, :background): para apps com serviço em segundo plano. Use exatamente um dos dois.
lib/watch/face/PayFace.mc, PayFaceScope.mcMostradores e campos de dados: a verificação em segundo plano, drawQr e o link nas configurações. Veja Mostradores e campos de dados.
lib/watch/extras/PayExtras.mcSó se você vende Avaliações e respostas ou usa uma loja: o pedido de avaliação, suas respostas e a tela "Já comprou?". Veja Extras no seu app. Relógios anteriores ao Connect IQ 3.1 a ignoram.
lib/watch/export/PayExport.mcSó se você vende Exportar para o celular: os dados do seu app como planilha, criptografados no relógio, com o link enviado ao celular do comprador.
lib/watch/feeds/PayFeeds.mcSó se o seu app usar feeds de dados: clima, sol e lua, horários de oração, marés e mais. Veja Feeds de dados.
lib/watch/resources/strings/pay.xmlAs 4 linhas que a tela de compra mostra sem o servidor, em inglês.
lib/watch/resources-<lang>/strings/pay.xmlAs mesmas 4 linhas nos outros 7 idiomas.

Adicione ao seu projeto

Descompacte a biblioteca ao lado da pasta do seu app:

IntervalTimer/
    manifest.xml
    monkey.jungle
    resources/
    source/
        PaywallConfig.mc
wearcheckout/
    lib/watch/...

Depois adicione as pastas dela ao seu jungle:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance
base.resourcePath = resources;../wearcheckout/lib/watch/resources
  • Só caminhos relativos. Um espaço num caminho absoluto quebra o jungle.
  • Ou copie os arquivos. Copiada para suas próprias pastas source e resources (e cada pasta resources-<lang>), a biblioteca não precisa de linha no jungle.
  • Nenhuma anotação para definir. Um build serve para todos os relógios. A subtela do Instinct é encontrada em tempo de execução.

Com serviço em segundo plano

Se o seu app tem serviço próprio em segundo plano, use glance-bg no lugar de glance, anote PaywallConfig com (:glance, :background) e adicione a permissão Background. Qualquer código (:background) faz o compilador pedir essa permissão, por isso há duas versões.

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance-bg

Libere a rede

O relógio consulta nosso servidor pela conexão do celular, ou pelo Wi-Fi nos relógios que têm. Adicione a permissão Communications:

manifest.xml
<iq:permissions>
    <iq:uses-permission id="Communications"/>
</iq:permissions>

PaywallConfig.mc

Baixe na aba Instalar do seu app: ele tem o endereço real do seu app. O endereço é público, não é um segredo.

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

(:glance)
module PaywallConfig {
    const URL = "https://pay.example/api/K7Q2/c";   // your app's address
    const TRIAL_DAYS = 7;
}
  • URL: o endereço do seu app. Toda verificação vai para lá.
  • TRIAL_DAYS: omita para não ter período de teste. Use o mesmo valor do período de teste no seu painel: o relógio nunca conta mais dias que TRIAL_DAYS.
  • A anotação corresponde ao PayScope.mc que você usa: (:glance), ou (:glance, :background) com glance-bg.

A linha única

Em getInitialView(), retorne suas views pela biblioteca:

source/YourApp.mc
return Paywall.gate([new MainView(), new MainDelegate()]);   // the whole app is paid for
return Paywall.start([new MainView(), new MainDelegate()]);  // or: only some features are
  • gate inicia o período de teste, consulta o servidor na hora certa e, enquanto bloqueado, mostra a tela de compra no lugar do seu app. BACK sai do app. Depois de pago, BACK ou START abre suas próprias views.
  • start abre seu app normalmente, com a tela de compra uma vez quando o período de teste termina. Depois, cada recurso pago verifica antes:
source/HistoryDelegate.mc
if (Paywall.unlocked()) { showHistory(); } else { Paywall.open(); }

Com qualquer um deles, uma compra feita no celular com a tela de compra fechada abre o desbloqueio sozinha quando o relógio fica sabendo. Bloquear recursos pagos lista cada chamada.

Um item Premium nas suas configurações

O item "Premium" de um menu de configurações abre a tela de compra. Se uma já estiver aberta, você vê essa: nunca há uma segunda.

source/SettingsDelegate.mc
Paywall.open();

Excluir dados

Se o seu app tem uma opção "Excluir dados", mantenha as chaves que Paywall.keys() retorna. O resto volta do servidor no próximo início.

source/SettingsDelegate.mc
// Delete data: everything except the payment keys
var st = Application.Storage;
var keep = Paywall.keys();
var saved = [];
for (var i = 0; i < keep.size(); i++) {
    saved.add(st.getValue(keep[i]));
}
st.clearValues();
for (var j = 0; j < keep.size(); j++) {
    if (saved[j] != null) {
        st.setValue(keep[j], saved[j]);
    }
}

Extras no seu app

Três dos extras pagos precisam de pasta própria, para os apps sem eles ficarem pequenos. Estatísticas dos relógios não precisa de nenhuma.

Avaliações e respostas, e "Já comprou?"

Adicione a pasta extras e ative-a antes da linha única:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/extras
source/YourApp.mc
PayExtras.on();
return Paywall.gate([new MainView(), new MainDelegate()]);
  • O pedido de avaliação aparece no dia 3, 7 ou 14: as estrelas, depois um QR code que abre sua página na loja e um recado para você.
  • Sua resposta aparece uma vez sobre o seu app. Em relógios pequenos, uma resposta longa ocupa duas telas: START mostra o resto.
  • "Já comprou?" mostra uma vez o código de um relógio novo quando o comprador pagou antes na sua página de loja.
  • Sem a pasta, os relógios desse app não recebem o pedido, suas respostas esperam no servidor, e um comprador da loja escaneia a tela de compra normal. Relógios anteriores ao Connect IQ 3.1 também ignoram a pasta.

Exportar para o celular

Adicione a pasta export, ofereça a exportação enquanto PayExport.ready() for true e inicie-a com um método que retorna uma linha por vez:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/export
source/ExportDelegate.mc
// Row 0 is the header; rows 1 to n are your data.
function row(i as Number) as Array {
    if (i == 0) { return ["Date", "Minutes"]; }
    var s = sessions[i - 1];
    return [s[:date], s[:minutes]];
}

if (PayExport.ready()) {
    PayExport.start(method(:row), sessions.size());
}
  • Valores podem ser texto, números, true ou false, ou null.
  • A biblioteca faz o resto: envia as partes criptografadas e depois envia o link ao celular do comprador como notificação do Garmin Connect. O comprador toca nela e o celular abre a planilha. START envia o link de novo. O link precisa do celular do comprador conectado ao relógio.
  • Fórmulas nunca rodam. Texto que começa com =, +, - ou @ ganha um ' na frente.

Feeds de dados

Adicione a pasta feeds e peça um feed onde seu app precisar. Seu método recebe o código HTTP e a resposta:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/feeds
source/MainView.mc
PayFeeds.get("weather", {
    "lat" => lat, "lon" => lon,
    "tz" => System.getClockTime().timeZoneOffset
}, method(:onWeather));

function onWeather(code as Number, data as Dictionary or Null) as Void {
    if (code == 200) {
        temp = data["now"]["temp"];
        WatchUi.requestUpdate();
    }
}
  • Os feeds: sol, lua, horários de oração, relógio mundial, câmbio, clima, alertas meteorológicos (EUA), terremotos, aurora, marés (EUA) e feriados. Os parâmetros e campos de cada um estão na página Feeds de dados do painel, onde você pode testá-los.
  • Guardado no relógio. Cada resposta vale pelo seu ttl, em segundos. Peça de novo antes disso, para o mesmo feed e quase o mesmo lugar, e a resposta guardada volta na hora, sem consultar.
  • Lugares são em graus. Horários vêm em segundos Unix, unidades métricas.
  • Mostre a linha da fonte quando o cartão do feed pedir, por exemplo "Clima: MET Norway".
  • Outros códigos trazem null: 403 significa que os Extras estão desativados para este app, 429 ou 503 significa tentar de novo mais tarde, e um código negativo é da Garmin (sem celular, sem rede). Relógios de teste têm todos os feeds grátis.
  • Custo: US$ 2 por milhão de requisições de relógios em produção, na sua fatura mensal. Uma resposta guardada no relógio não custa nada.

Estatísticas dos relógios

Sem código: o modelo do relógio vem em cada verificação. Para ver também as versões do seu app, adicione uma versão a PaywallConfig:

source/PaywallConfig.mc
const VERSION = "1.3";

Idiomas

A biblioteca fala inglês, alemão, francês, espanhol, português, coreano e chinês (simplificado e tradicional). O idioma do próprio relógio decide. Qualquer outro idioma recebe inglês.

  • As telas vêm do nosso servidor no idioma do relógio, então corrigir um texto não exige atualizar o app.
  • Só 4 linhas ficam no relógio, para quando ainda não há resposta do servidor.
StringInglêsQuando aparece
PwWaitCarregando…Antes da primeira resposta
PwPhoneOfflineSem celular, Bluetooth ou internet
PwBusyTente mais tardeO servidor não respondeu direito
PwBackBACK para fecharSem nenhuma resposta para mostrar

Adicione uma linha no jungle por idioma. Mantenha sua própria pasta primeiro; omita essa parte para um idioma sem pasta no seu app.

monkey.jungle
base.lang.deu = resources-deu;../wearcheckout/lib/watch/resources-deu
base.lang.fre = resources-fre;../wearcheckout/lib/watch/resources-fre
base.lang.spa = resources-spa;../wearcheckout/lib/watch/resources-spa
base.lang.por = resources-por;../wearcheckout/lib/watch/resources-por
base.lang.kor = resources-kor;../wearcheckout/lib/watch/resources-kor
base.lang.zhs = resources-zhs;../wearcheckout/lib/watch/resources-zhs
base.lang.zht = resources-zht;../wearcheckout/lib/watch/resources-zht

O que verificar

  • A string com o nome do seu app. Sem resposta para mostrar, a tela de compra mostra sua string AppName. Mantenha essa string nos seus recursos.
  • Timers. A tela de compra usa um timer, e PayExtras mais um. Os relógios permitem só alguns, e "Too Many Timers" encerra o app: se o seu já usa dois ou mais, confira se fica dentro do limite.
  • Botão segurado. Segurar um botão por muito tempo abre o menu do próprio relógio. A tela de compra só reage a pressionamentos curtos.
  • Chamadas antigas continuam funcionando. Paywall.startTrial(); Paywall.launch(); em getInitialView(), e Paywall.showOver() no onShow() da sua primeira tela, fazem o que gate e start fazem numa linha.
Esc