> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gifty.lat/llms.txt
> Use this file to discover all available pages before exploring further.

# O ciclo de um vale-presente

> Uma referência para produto, pedido, emissão, entrega e resgate.

export const GiftJourney = ({locale = "es-AR", fallback, fallbackHref}) => {
  const L = locale === "en" ? "en" : locale === "pt-BR" ? "pt" : "es";
  const T = {
    es: {
      t: "El recorrido de un regalo",
      step: "Paso",
      of: "de",
      prev: "Paso anterior",
      next: "Paso siguiente",
      play: "Reproducir",
      pause: "Pausar",
      rule: "Regla clave",
      q: "En cola",
      d: "Entregado",
      on: "Online",
      ct: "Mostrador",
      fb: "Leé estas reglas en texto",
      s: [["Producto", "El producto define la oferta", "Montos, vigencia, textos y diseño definen la oferta. El producto se usa para vender o emitir regalos.", "Un producto todavía no es un regalo: nadie tiene saldo hasta la emisión."], ["Pedido", "Un pedido puede tener varias unidades", "Cada unidad se configura por separado: para quién es, con qué mensaje y cuándo se envía. Tres unidades son tres futuros regalos.", "Cada unidad pendiente necesita su configuración; otras unidades del pedido pueden estar emitidas."], ["Emisión", "La emisión crea cada regalo y su saldo", "Al emitirse, cada unidad se convierte en un regalo con código y saldo propios. Confirmar el pedido no demuestra que todas sus unidades estén emitidas.", "Reemitir es una emisión nueva. No reenvía nada."], ["Entrega", "La entrega envía ESE regalo", "El canal disponible lleva un regalo puntual al destinatario. En cola no demuestra entrega: revisá el resultado final en la cronología.", "Si la entrega falla, reintentala para el mismo regalo. Reemitir NO es reintentar la entrega."], ["Canje", "El canje consume el saldo", "La persona usa el saldo del regalo comprando online o en el mostrador de tu local.", "Revisá importe y comprobante. Si queda un intento pendiente, resolvelo desde la misma operación."]]
    },
    en: {
      t: "The journey of a gift",
      step: "Step",
      of: "of",
      prev: "Previous step",
      next: "Next step",
      play: "Play",
      pause: "Pause",
      rule: "Key rule",
      q: "Queued",
      d: "Delivered",
      on: "Online",
      ct: "Counter",
      fb: "Read these rules as text",
      s: [["Product", "The product defines the offer", "Amounts, validity, copy and design define the offer. The product is used to sell or issue gifts.", "A product is not a gift yet: nobody holds a balance until issuance."], ["Order", "An order can hold several units", "Each unit is configured on its own: who it is for, the message, and when it is sent. Three units are three future gifts.", "Each pending unit needs configuration; other units in the order may already be issued."], ["Issuance", "Issuance creates each gift and its balance", "At issuance, each unit becomes a gift with its own code and balance. Order confirmation does not prove every unit is issued.", "Reissuing is a new issuance. It does not resend anything."], ["Delivery", "Delivery sends THAT gift", "The available channel carries one specific gift to its recipient. Queued is not proof of delivery: check the final timeline result.", "If a delivery fails, retry it for the same gift. Reissuing is NOT retrying delivery."], ["Redemption", "Redemption consumes the balance", "The recipient spends the gift balance by buying online or at your store counter.", "Check amount and receipt. If an attempt remains pending, resolve it from the same operation."]]
    },
    pt: {
      t: "A jornada de um presente",
      step: "Etapa",
      of: "de",
      prev: "Etapa anterior",
      next: "Próxima etapa",
      play: "Reproduzir",
      pause: "Pausar",
      rule: "Regra-chave",
      q: "Na fila",
      d: "Entregue",
      on: "Online",
      ct: "Balcão",
      fb: "Leia estas regras em texto",
      s: [["Produto", "O produto define a oferta", "Valores, validade, textos e design definem a oferta. O produto é usado para vender ou emitir presentes.", "Um produto ainda não é um presente: ninguém tem saldo até a emissão."], ["Pedido", "Um pedido pode ter várias unidades", "Cada unidade é configurada separadamente: para quem é, com qual mensagem e quando será enviada. Três unidades são três futuros presentes.", "Cada unidade pendente precisa de configuração; outras unidades do pedido podem já estar emitidas."], ["Emissão", "A emissão cria cada presente e seu saldo", "Na emissão, cada unidade vira um presente com código e saldo próprios. Confirmar o pedido não comprova emissão de todas as unidades.", "Reemitir é uma nova emissão. Não reenvia nada."], ["Entrega", "A entrega envia AQUELE presente", "O canal disponível leva um presente específico ao destinatário. Na fila não comprova entrega: confira o resultado final na linha do tempo.", "Se a entrega falhar, tente de novo para o mesmo presente. Reemitir NÃO é reenviar."], ["Resgate", "O resgate consome o saldo", "A pessoa usa o saldo do presente comprando online ou no balcão da sua loja.", "Confira valor e comprovante. Se uma tentativa ficar pendente, resolva na mesma operação."]]
    }
  };
  const c = T[L];
  const [i, setI] = useState(0);
  const [playing, setPlaying] = useState(false);
  const [rm, setRm] = useState(false);
  useEffect(() => {
    const m = window.matchMedia("(prefers-reduced-motion: reduce)");
    const sync = () => {
      setRm(m.matches);
      if (m.matches) setPlaying(false);
    };
    sync();
    m.addEventListener("change", sync);
    return () => m.removeEventListener("change", sync);
  }, []);
  useEffect(() => {
    if (!playing || rm) return;
    const id = setInterval(() => setI(s => {
      if (s >= 4) {
        setPlaying(false);
        return 4;
      }
      return s + 1;
    }), 5000);
    return () => clearInterval(id);
  }, [playing, rm]);
  const s = c.s[i];
  const icons = ["M3 3h8l9 9-8 8-9-9zM7 7h.01", "M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM14 14h6v6h-6z", "M4 8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 0 0 4v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-4z", "M4 12l16-8-6 16-2-6z", "M5 12l5 5 9-11"];
  const tk = "M0 8a8 8 0 0 1 8-8h40a8 8 0 0 1 8 8v20a6 6 0 0 0 0 12v20a8 8 0 0 1-8 8H8a8 8 0 0 1-8-8V48a6 6 0 0 0 0-12z";
  const scenes = [<g><rect x="50" y="24" width="140" height="112" rx="12" className="gj-card" /><path d="M70 44h30l22 22-22 22H70z" className="gj-acc-s" /><circle cx="80" cy="54" r="3" className="gj-acc-f" /><rect x="132" y="48" width="40" height="8" rx="4" className="gj-bar" /><rect x="132" y="66" width="28" height="8" rx="4" className="gj-bar" /><rect x="70" y="100" width="100" height="8" rx="4" className="gj-bar" /><rect x="70" y="116" width="64" height="8" rx="4" className="gj-bar" /></g>, <g>{[0, 1, 2].map(k => <g key={k} transform={`translate(${28 + k * 64} 40)`}><rect width="56" height="80" rx="10" className="gj-card" /><circle cx="28" cy="24" r="10" className={k === 1 ? "gj-acc-f" : "gj-bar"} /><rect x="12" y="44" width="32" height="6" rx="3" className="gj-bar" /><rect x="12" y="58" width={[22, 30, 18][k]} height="6" rx="3" className="gj-bar" /></g>)}</g>, <g>{[0, 1, 2].map(k => <g key={k} transform={`translate(${28 + k * 64} 48)`}><path d={tk} className="gj-card" /><rect x="10" y="14" width="36" height="6" rx="3" className="gj-bar" /><rect x="10" y="42" width="36" height="8" rx="4" className="gj-acc-f" /></g>)}</g>, <g><g transform="translate(24 52)"><path d={tk} className="gj-card gj-acc-s" /><rect x="10" y="42" width="36" height="8" rx="4" className="gj-acc-f" /></g><path d="M92 80h44m-8-8l8 8-8 8" className="gj-line" /><g transform="translate(148 36)"><circle cx="20" cy="20" r="16" className="gj-ring" /><path d="M20 10v10l6 4" className="gj-line" /><text x="44" y="24" className="gj-t">{c.q}</text></g><g transform="translate(148 88)"><circle cx="20" cy="20" r="16" className="gj-acc-f" /><path d="M12 20l6 6 10-12" className="gj-line-inv" /><text x="44" y="24" className="gj-t">{c.d}</text></g></g>, <g><g transform="translate(24 52)"><path d={tk} className="gj-card" /><rect x="10" y="42" width="36" height="8" rx="4" className="gj-bar" /><rect x="10" y="42" width="16" height="8" rx="4" className="gj-acc-f" /></g><path d="M92 80h36" className="gj-line" /><g transform="translate(140 36)"><circle cx="20" cy="20" r="14" className="gj-ring" /><path d="M6 20h28M20 6c-8 8-8 20 0 28M20 6c8 8 8 20 0 28" className="gj-line" /><text x="44" y="24" className="gj-t">{c.on}</text></g><g transform="translate(140 88)"><path d="M6 16l4-10h20l4 10v18H6z" className="gj-ring" /><path d="M6 16h28M14 34V24h12v10" className="gj-line" /><text x="44" y="24" className="gj-t">{c.ct}</text></g></g>];
  return <section className="gj" aria-label={c.t}>
      <div className="gj-head">
        <div><h3 className="gj-title">{c.t}</h3><p className="gj-count">{c.step} {i + 1} {c.of} 5</p></div>
        <div className="gj-ctl">
          <button type="button" className="gj-btn" aria-label={c.prev} onClick={() => {
    setPlaying(false);
    setI(Math.max(0, i - 1));
  }} disabled={i === 0}><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M15 6l-6 6 6 6" /></svg></button>
          <button type="button" className="gj-btn" aria-label={c.next} onClick={() => {
    setPlaying(false);
    setI(Math.min(4, i + 1));
  }} disabled={i === 4}><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 6l6 6-6 6" /></svg></button>
          {!rm && <button type="button" className="gj-btn gj-play" aria-pressed={playing} onClick={() => {
    if (i === 4) setI(0);
    setPlaying(!playing);
  }}>{playing ? c.pause : c.play}</button>}
        </div>
      </div>
      <ol className="gj-rail">
        {c.s.map((x, k) => <li key={k}><button type="button" className={"gj-step" + (k === i ? " is-on" : k < i ? " is-done" : "")} aria-current={k === i ? "step" : undefined} onClick={() => {
    setI(k);
    setPlaying(false);
  }}>
            <span className="gj-badge"><svg viewBox="0 0 24 24" aria-hidden="true"><path d={icons[k]} /></svg></span><span>{k + 1}. {x[0]}</span>
          </button></li>)}
      </ol>
      <div className="gj-panel" key={i}>
        <svg className="gj-scene" viewBox="0 0 300 160" role="img" aria-label={s[1]}>{scenes[i]}</svg>
        <div><h4 className="gj-h">{s[1]}</h4><p className="gj-p">{s[2]}</p><p className="gj-rule"><strong>{c.rule}</strong> {s[3]}</p></div>
      </div>
      <p className="gifty-visually-hidden" aria-live="polite">{c.step} {i + 1} {c.of} 5: {s[1]}</p>
      <p className="gj-fb">{fallbackHref ? <a href={fallbackHref}>{fallback || c.fb}</a> : fallback || c.fb}</p>
    </section>;
};

<GiftJourney locale="pt-BR" fallback="Leia a explicação completa em texto." fallbackHref="#do-produto-ao-resgate" />

Um vale-presente passa por processos diferentes. Separá-los ajuda a identificar onde agir e evita confundir pagamento, envio e resgate.

## Do produto ao resgate

| Etapa                    | O que representa                                            | O que não comprova sozinha                               |
| ------------------------ | ----------------------------------------------------------- | -------------------------------------------------------- |
| Produto de vale-presente | A opção publicada no catálogo da loja.                      | Que alguém tenha comprado.                               |
| Pedido pago              | A compra que precisa ser processada.                        | Que todas as unidades estejam configuradas e entregues.  |
| Configuração             | Os dados necessários para cada presente e destinatário.     | Que a emissão terminou.                                  |
| Emissão                  | A criação do vale-presente de uma unidade.                  | Que o destinatário recebeu a mensagem.                   |
| Entrega                  | As tentativas e os resultados do envio desse vale-presente. | Que o destinatário abriu ou resgatou.                    |
| Presente público         | A página que o destinatário abre pelo link.                 | Uma nova compra ou um resgate concluído.                 |
| Resgate                  | O uso do valor e a atualização do saldo.                    | Que o vale-presente se esgotou quando o uso foi parcial. |

A emissão manual começa por uma ação do lojista, sem exigir um pedido do checkout. A documentação distingue essa entrada da compra online.

## Integrações atuais e limites

Tiendanube/Nuvemshop é a plataforma de ecommerce deste percurso. Marketing Nube tem uma área própria de conexão e públicos; consulte essa integração para entender o alcance. Essas conexões não significam que exista uma API pública transacional do gifty.

## API pública: indisponível

**A API pública transacional não está disponível.** Este piloto não documenta endpoint público para emitir, consultar saldos ou resgatar. Não invoque `POST /gift-cards` nem deduza um contrato a partir de rotas internas do app.

Uma futura referência de API deverá definir autenticação, permissões, idempotência, erros, limites e versionamento sobre uma implementação aprovada. Esta página não anuncia data nem contrato dessa API.

## Informações para agentes

As páginas públicas explicam o produto e permitem citar suas regras. Elas não autorizam acesso aos dados de uma loja. O saldo de um código específico exige leitura autenticada e permitida; não pode ser inferido desta documentação.

O Markdown é gerado a partir do mesmo conteúdo editorial. Os SVGs têm equivalentes em texto. Os índices de conhecimento são documentais, não ferramentas para executar operações no gifty.

## Se precisar de ajuda com um caso

Identifique a etapa, a referência da operação e o resultado observado. O atendimento humano usa o canal de WhatsApp do gifty; esta documentação não inicia conversa nem confirma o recebimento de um caso. Clicar em um link não equivale a uma mensagem recebida.

[Guia de emissão e entrega](/pt-BR/issue-and-deliver) · [Conceito de saldo](/pt-BR/balance)

[Ler esta página em Markdown](/exports/pt-BR/gift-lifecycle.md)
