docs: developer documentation & customer-facing polish
All checks were successful
Build and Deploy / deploy (push) Successful in 45s
All checks were successful
Build and Deploy / deploy (push) Successful in 45s
Code documentation: - client.py: docstrings with Tink API docs URLs on every method - demo.py: docstrings on all route handlers explaining Tink flow context - webhook receiver: C# HMAC-SHA256 signature verification example Customer-facing cleanup: - Removed 'sales demo' / 'MoneyCapp × Tink' internal branding - Neutral footer, consistent terminology (external_user_id, not tink_external_ref) - Sandbox note on Step 3: anonymous flow vs production authorization_code flow - Step 6: 'Next Steps for C#/.NET implementation' section - demo_data.py: dynamic relative dates (no hardcoded year) - print() → logging.getLogger, /debug-session gated behind DEMO_MODE - Step 1 always resets session state (fresh start on every visit) - README: neutral/collaborative tone, what-it-is-not section Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
<div class="w-8 h-8 rounded-lg bg-violet-600 flex items-center justify-center text-white font-bold text-sm">T</div>
|
||||
<div>
|
||||
<span class="font-semibold text-white">Tink API Demo</span>
|
||||
<span class="text-slate-400 text-sm ml-2">MoneyCapp × Tink</span>
|
||||
<span class="text-slate-400 text-sm ml-2">Open Banking Demo</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="border-t border-slate-800 text-center text-slate-500 text-xs py-4">
|
||||
Tink API Demo — MoneyCapp sales prototype — i80.dk
|
||||
Tink Open Banking API Demo
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -117,6 +117,19 @@
|
||||
{% else %}
|
||||
<!-- Not yet connected — show connection UI -->
|
||||
|
||||
<!-- Sandbox note: anonymous flow vs production -->
|
||||
<div class="bg-amber-950/40 border border-amber-700/40 rounded-xl px-5 py-3.5 flex items-start gap-3 text-sm">
|
||||
<svg class="w-4 h-4 text-amber-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
<div class="text-amber-200/80 leading-relaxed">
|
||||
<span class="font-semibold text-amber-300">Sandbox-note:</span>
|
||||
Dette demo bruger <em>anonymous Tink Link flow</em> (ingen <code class="font-mono text-xs">authorization_code</code> i URL'en) —
|
||||
en sandbox-begrænsning. I produktion <strong>skal</strong> du kalde
|
||||
<code class="font-mono text-xs">authorization-grant/delegate</code> og sende koden med til Tink Link,
|
||||
så bank-forbindelsen bindes til den korrekte Tink-bruger.
|
||||
<a href="https://docs.tink.com/resources/tink-link/tink-link-web-permanent-users" target="_blank" class="text-amber-400 underline hover:text-amber-300 ml-1">Docs ↗</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PRIMARY: direct callback flow -->
|
||||
<div class="bg-slate-900 border border-emerald-700/40 rounded-xl p-5 space-y-4">
|
||||
<div class="flex items-start gap-3">
|
||||
|
||||
@@ -38,9 +38,11 @@
|
||||
<span class="ml-2 text-xs px-2 py-0.5 rounded-full font-mono font-semibold bg-slate-800 text-slate-400 border border-slate-700">v1</span>
|
||||
</div>
|
||||
<p class="text-slate-400 text-sm mt-2 max-w-2xl">
|
||||
Opret en Tink-bruger med en <code class="text-violet-300">tink_external_ref</code> —
|
||||
MoneyCapp's interne reference til kunden i Tink. Gemmes i jeres kundedatabase som <code class="text-violet-300">tink_external_ref</code> (ikke jeres interne <code class="text-slate-400">customer_id</code>).
|
||||
Tink returnerer et <code class="text-violet-300">user_id</code> som bruges i efterfølgende kald.
|
||||
Opret en Tink-bruger med et <code class="text-violet-300">external_user_id</code> —
|
||||
jeres interne reference til kunden (f.eks. et kundenummer eller UUID fra jeres database).
|
||||
Gem dette som en kolonne i jeres kundedatabase (<code class="text-violet-300">tink_user_ref</code> el.lign.) —
|
||||
det er ikke det samme som jeres interne <code class="text-slate-400">customer_id</code>.
|
||||
Tink returnerer et <code class="text-violet-300">user_id</code> (UUID) der bruges i efterfølgende kald.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -89,8 +91,8 @@
|
||||
<div class="px-5 py-4 border-b border-slate-800">
|
||||
<p class="text-sm font-semibold text-white">Hvem opretter vi?</p>
|
||||
<p class="text-xs text-slate-400 mt-0.5">
|
||||
<code class="text-violet-300">tink_external_ref</code> = jeres reference til kunden i Tink —
|
||||
adskilt fra jeres interne <code class="text-slate-400">customer_id</code>
|
||||
<code class="text-violet-300">external_user_id</code> = jeres interne kundereference —
|
||||
gemmes i jeres database som f.eks. <code class="text-slate-400">tink_user_ref</code>
|
||||
</p>
|
||||
</div>
|
||||
<form method="POST" action="/demo/step/2" class="p-5 space-y-4">
|
||||
@@ -101,7 +103,7 @@
|
||||
value="Henrik Jess"
|
||||
class="w-full bg-slate-950 border border-slate-700 rounded-lg px-4 py-2.5 text-white text-sm font-mono
|
||||
placeholder-slate-600 focus:outline-none focus:border-violet-500 focus:ring-1 focus:ring-violet-500/30 transition">
|
||||
<p class="text-xs text-slate-600 mt-1.5">→ <code class="text-violet-300/70">tink_external_ref</code> = <code class="text-violet-300/70">moneycapp-henrik-jess-a3f9c1</code></p>
|
||||
<p class="text-xs text-slate-600 mt-1.5">→ <code class="text-violet-300/70">external_user_id</code> = <code class="text-violet-300/70">moneycapp-henrik-jess-a3f9c1</code></p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Marked</label>
|
||||
@@ -136,13 +138,13 @@
|
||||
<p class="text-xs text-slate-500 uppercase tracking-wider mb-3">API endpoint</p>
|
||||
<code class="text-emerald-400 font-mono text-sm">POST https://api.tink.com/api/v1/user/create</code>
|
||||
<div class="mt-3 bg-slate-950 rounded-lg p-3 overflow-x-auto">
|
||||
<pre class="text-xs text-amber-300 font-mono whitespace-pre"># MoneyCapp DB:
|
||||
# customer_id = 42 ← jeres interne ID (Tink ser det aldrig)
|
||||
# tink_external_ref = "moneycapp-42-a3f9c1" ← Tink-reference
|
||||
<pre class="text-xs text-amber-300 font-mono whitespace-pre"># Your DB schema (example):
|
||||
# customer_id = 42 ← your internal ID (Tink never sees this)
|
||||
# tink_user_ref = "moneycapp-42-a3f9c1" ← store Tink's external_user_id here
|
||||
|
||||
# Request body
|
||||
{
|
||||
"external_user_id": "moneycapp-<ref>", ← tink_external_ref
|
||||
"external_user_id": "moneycapp-<ref>", ← your reference, stored in DB
|
||||
"market": "DK",
|
||||
"locale": "da_DK"
|
||||
}
|
||||
|
||||
@@ -223,8 +223,7 @@ async def tink_webhook(request: Request):
|
||||
Fra brugeroprettelse over live bankdata til real-time webhooks — alt via Tink API.
|
||||
</p>
|
||||
<p class="text-slate-500 text-sm mb-6 max-w-xl mx-auto">
|
||||
Vi har vist: auth → bruger → bank-tilslutning → konti (v2) → transaktioner (v2) → webhooks.
|
||||
Det er præcis hvad MoneyCapp mangler for at gøre deres integration robust.
|
||||
Auth → bruger → bank-tilslutning → konti (v2) → transaktioner (v2) → webhooks.
|
||||
</p>
|
||||
<div class="flex gap-3 justify-center flex-wrap">
|
||||
<a href="/demo/reset" class="px-5 py-2.5 border border-slate-600 text-slate-300 hover:text-white hover:border-slate-400 rounded-xl text-sm transition">↺ Kør demo igen</a>
|
||||
@@ -235,6 +234,33 @@ async def tink_webhook(request: Request):
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Next Steps for implementation -->
|
||||
<div class="mt-6 bg-slate-900/60 border border-slate-800 rounded-2xl p-7">
|
||||
<h4 class="text-white font-semibold text-base mb-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
|
||||
Næste skridt mod en produktion-klar integration
|
||||
</h4>
|
||||
<div class="grid md:grid-cols-2 gap-3 text-sm text-slate-400">
|
||||
<div class="bg-slate-800/60 rounded-lg p-4 space-y-1.5">
|
||||
<p class="text-violet-300 font-semibold text-xs uppercase tracking-wider mb-2">Backend (C# / .NET)</p>
|
||||
<p>1. Lav en <code class="text-violet-300 font-mono text-xs">TinkApiClient</code> wrapper (brug <code class="text-xs font-mono">tink/client.py</code> som reference)</p>
|
||||
<p>2. Gem <code class="text-violet-300 font-mono text-xs">external_user_id</code> + <code class="text-violet-300 font-mono text-xs">user_id</code> i din kundedatabase</p>
|
||||
<p>3. Implementér <code class="text-violet-300 font-mono text-xs">/callback</code> endpoint med token exchange</p>
|
||||
<p>4. Gem tokens sikkert (encrypted, server-side — ikke i cookie)</p>
|
||||
</div>
|
||||
<div class="bg-slate-800/60 rounded-lg p-4 space-y-1.5">
|
||||
<p class="text-violet-300 font-semibold text-xs uppercase tracking-wider mb-2">Webhooks & Production</p>
|
||||
<p>5. Byg webhook receiver med <a href="https://docs.tink.com/api#webhook/webhook-endpoints" target="_blank" class="text-violet-400 hover:text-violet-300 underline">HMAC-SHA256 signature verification</a></p>
|
||||
<p>6. Skift til production Tink-credentials (Tink Console)</p>
|
||||
<p>7. Registrér din production callback URI i Tink Console</p>
|
||||
<p>8. Brug <code class="text-violet-300 font-mono text-xs">authorization-grant/delegate</code> i prod-flowet (ikke anon)</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-xs text-slate-600 mt-4">
|
||||
Kildekoden til dette demo (<code class="font-mono">src/tink/client.py</code> og <code class="font-mono">src/routes/demo.py</code>) er skrevet for at være letlæselig og direkte overførbar til andre platforme.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="mt-4 flex justify-start">
|
||||
<a href="/demo/step/5"
|
||||
|
||||
Reference in New Issue
Block a user