Vibe Coding — your first app without knowing how to code — 8. Connecting services: emails, payment, AI

19 min read min de lecture
Chapter 08

Connecting services: emails, payment, AI

Chapter 8 of 10 · 80%

Chapter objectives

  • Understand what an API is and how your app talks to external services
  • Send emails and accept a payment without coding
  • Add an AI feature while keeping secret keys server-side

The app that talks to the world

The success of Tom's app reaches beyond his class: a colleague who teaches French uses it with her eighth-graders, and a math teacher from another school wrote to ask "how to set it up for his school — and how much it costs". Three wishes emerge: send students a weekly recap by email, add an AI-generated encouragement message when a student finishes their day, and offer a paid "classroom" version for teachers at other schools. Three features, one shared mechanism: making his app talk to external services.

That dialogue happens through APIs (programming interfaces). The principle: a service — Resend for emails, Stripe for payment, Claude for AI — exposes a counter on the Internet. Your app shows up with a structured request ("send this email to this address") and an API key that proves its identity, and the service executes then replies. You don't need to understand how Resend routes an email, any more than you need to understand a power plant to plug into an outlet: the API is the outlet.

The golden rule: keys stay server-side

Before any wiring, an absolute rule. Your API key is a bank card: whoever holds it consumes the service in your name and at your expense. And all the code running in a browser is readable by anyone — a simple F12 is enough. The inescapable conclusion: a secret key must never sit in browser-side code. It lives server-side, where nobody can read it.

"But I don't have a server!" Yes you do, almost: Vercel (and its competitors) offers server functions — small pieces of code hosted on their side, executed on demand. The pattern is always the same: the browser calls your server function (no key), the function calls the external service (with the key, stored in an environment variable), and returns only the result to the browser. The AI knows how to create these functions perfectly — your job is to demand this architecture in your prompts.

flowchart LR
  N["Student's browser"] -->|"Request without any key"| F["Server function on Vercel"]
  F -->|"Call with the secret key"| S["External service: Resend, Stripe or Claude"]
  S -->|"Response"| F
  F -->|"Clean result"| N
The sandwich architecture: the secret key never leaves the server.
Test yourself: open your deployed app, F12, "Sources" tab, and search for the word "key" in the files. If a secret key appears, it's compromised — revoke it immediately in the service's dashboard and ask the AI to move the call server-side. This two-minute check should follow every integration.

Sending emails: the weekly recap

First connection: email. You don't send automated emails from your Gmail inbox — providers block it fast and it's fragile. You go through a transactional email service like Resend, Postmark or Brevo: built for apps, reliable, and free at small scale (Resend offers 100 emails per day, far beyond Tom's needs). Tom's prompt, in full:

PROMPT
Add a recap email feature to my habit-tracking app.
Context: HTML/JS app on Vercel, data in Supabase, magic link authentication.
What I want:
1. a "send me my weekly recap" button on the main page
2. on click, a Vercel server function computes the logged-in user's streaks and checks for the week, and sends them a clean, readable email via Resend
3. the Resend API key stays server-side, in a Vercel environment variable — never in browser code
4. strict limit: one send per user per day maximum, with a clear message if the limit is reached
First guide me through creating the Resend account and configuring the environment variable on Vercel, then code the function.
One step at a time, I'll wait to test before the next one.

Pause on line 4: "one send per user per day". Why limit a free feature? Because any button that triggers an external service can be hammered — by a prankster student or by a bot — and every send consumes your quota. Setting a limit at design time is an architect's reflex: you protect your service before it needs it. We'll generalize this reflex in chapter 9.

Taking a payment without coding: Stripe Payment Links

For the paid "classroom" version, Tom fears the worst: online payment is serious, regulated, anxiety-inducing. Good surprise: Stripe, the payment service most used by developers, offers Payment Links — payment pages hosted by Stripe, created in a few clicks in their dashboard, without a single line of code. You create a product ("Classroom plan — $29/year"), Stripe generates a URL, and your app only has to show a button pointing to that URL. Stripe handles the bank card, security, invoicing, refunds.

  • Create an account on stripe.com and stay in test mode for now.
  • In the dashboard: Products → add "Classroom plan" with its price.
  • Generate the product's Payment Link and copy the URL.
  • Ask the AI to add a "classroom plan" page with the benefits and a button to that link.
  • Test the full journey in test mode, then switch to live mode once everything is validated.
In test mode, Stripe accepts the dummy card 4242 4242 4242 4242 (any future date and any code): you can run through a real purchase journey without spending a cent. Only switch to live mode after testing the complete journey, confirmation email included.

Payment Links have limits — no automatic feature unlocking in the app after payment, for instance. For Tom's v1, that's perfect: the teacher pays via the link, Tom receives the Stripe notification and activates the classroom by hand. Five customers a month is manageable manually; the day there are fifty, he'll wire up the automation (the "webhooks") — a nice problem to have, for later. Automating something that happens only five times a month is a bad deal.

Adding a touch of AI to your app

Last connection, the most delightful: using AI inside your app — and no longer just to build it. Tom's idea: when a student checks off their last habit of the day, a short personalized encouragement message appears, generated by the Claude API. Same architecture as the email: server function, key in an environment variable, usage limit. With two new precautions, specific to AI:

PROMPT
Add a "daily encouragement" feature to my habit-tracking app.
When the user checks off their last habit of the day, call the Claude API from a Vercel server function to generate a short personalized encouragement message:
- warm but not cheesy tone, suited to middle-schoolers
- mention the current streak and the most consistent habit of the week
- 2 sentences maximum, in English
Technical constraints:
1. the API key stays in an environment variable, server-side only
2. limit: one call per user per day
3. plan a nice default message if the call fails or takes more than 5 seconds — the app must NEVER break because of this feature
Show me the exact text of the prompt the function will send to Claude, so I can adjust it.

Two lines deserve your attention. "Plan a default message if the call fails": that's graceful degradation — a bonus feature must never be able to break the app that carries it. And "show me the exact text of the prompt": that's right, your app now contains a prompt of its own, which you can refine just like you learned to refine yours. You write prompts that generate code that sends prompts — the loop is delicious, and you're in control of every level.

Unlike Resend or Stripe, every call to an AI API costs a fraction of a cent — harmless per unit, dangerous without a limit. Three protections from day one: a per-user call limit, a monthly spending cap in the provider's dashboard, and an eye on the usage page during the first week. Surprise-bill stories always start with "I'll add a limit later".

When an external service goes down

Last lesson of this chapter: your app now depends on services you don't control. Resend, Stripe or the Claude API can have an outage, slow down, or change their rules. Three proportionate habits: check the service's status page before hunting for the bug on your side ("Resend status" in a search engine), plan a fallback behavior for every connection (default message, disabled button with an explanation), and never make your app's core feature depend on an external service. Tom's habits can be checked off even if the AI, the email and the payment are all three down — that's what a healthy architecture looks like.

Your app now knows how to write, charge and think. But each connection has also enlarged its exposure surface: keys to protect, inputs to validate, limits to enforce. Before going further, it's time to seriously secure the whole thing — that's the agenda of chapter 9.

🛠️ Your turn

Context

Tom plans his three connections over two weeks, in order of value: first the email recap (requested by the students), then the AI encouragement (his personal pride), finally the Payment Link (for the impatient colleague). For your own app, pick ONE connection that makes sense — email, payment or AI — and build it end to end with the secure architecture. Just one, but done well.

Instructions

  1. Pick your connection and write the user value in two sentences (if you can’t, pick another one).
  2. Create the account for the relevant service (Resend, Stripe or Anthropic) and locate the API key and the usage page.
  3. Send your prompt demanding: a server function, the key in an environment variable, a per-user usage limit, a fallback behavior.
  4. Configure the environment variable on Vercel following the AI’s guidance, then test the feature end to end.
  5. Run the leak check: F12 → Sources → search for "key" — no secret key must appear browser-side.
  6. Test the limit (trigger twice, verify the polite refusal) and the fallback (ask the AI how to simulate a service outage), then commit.
Hint — If the feature works locally but fails once deployed, it's almost always the missing environment variable on Vercel: they're configured separately for production, in the project settings. Check that before any other debugging.

In summary

  • An API is a counter: your app sends a structured request with its key, the service executes and replies.
  • Golden rule: secret keys live server-side (Vercel functions + environment variables), never in the browser.
  • Automated emails = a transactional service (Resend…), never your personal inbox.
  • Stripe Payment Links: a real payment page without a line of code — and a test mode with the 4242 card.
  • An AI feature in your app is a server-side prompt: refine it the way you refine your own.
  • Every connection gets, from day one: a usage limit, a spending cap and a fallback behavior.
  • Your app’s core must never depend on an external service: any bonus must be able to fail without breaking anything.

Quiz — check your understanding

1. Why must a secret API key never sit in browser-side code?

A simple F12 reveals all of a page's code. An exposed key is your service "bank card" out in the wild: the sandwich architecture is mandatory — browser → server function → service.

2. What is the role of a server function (Vercel-style) in this architecture?

The server function is the trusted intermediary: it holds the key (in an environment variable) and exposes a secret-free endpoint to the browser.

3. Why does Tom pick Stripe Payment Links rather than a full integration?

Five customers a month can be activated by hand painlessly. Automating (webhooks) becomes worthwhile at fifty — sizing the effort to the real need is an architect's reflex.

4. What should Tom’s app do if the AI API call fails?

That's graceful degradation: the app's core (checking off habits) stays intact no matter what happens to the bonuses. Every external feature has a fallback behavior.

5. Which protections should you set from day one on an AI API connection?

Every call costs money: without a limit or a cap, a hammered button becomes a surprise bill. The three protections take ten minutes and spare you the horror stories.

Auteur(s)

R

REHOUMA Haythem

Haythem Rehouma est un ingénieur et architecte IA et cloud, formateur et enseignant technique, avec un profil orienté IA médicale, AWS, MLOps, LLM/RAG et vision par ordinateur.