Problem

Indian SMB owners, freelancers, and startups often need to share newly generated contracts—NDAs, employment contracts, service agreements—quickly with clients or partners. Sending a PDF by email or uploading it to a cloud folder adds friction and delays the signing process. This is where contract generator pays off in practice.

How the Feature Works

DoAide Contracts adds a single‑click WhatsApp share button after a contract is generated. The flow is:

  1. Generate: The user selects a template (e.g., employment contract template) and fills in the form.
  2. Store: FastAPI saves the contract as a PDF blob in PostgreSQL and returns a contract ID.
  3. Share: The React UI renders a Share via WhatsApp button. When clicked, it calls a FastAPI endpoint that streams the PDF to the WhatsApp Business API.
  4. Confirm: A toast informs the user that the contract was sent.

The user never leaves the site; the contract is delivered instantly to the chosen WhatsApp contact. Getting contract generator right early saves rework later.

Frontend Implementation

The share button lives in components/ShareWhatsAppButton.jsx:

import { useState } from "react"; export default function ShareWhatsAppButton({ contractId, recipient }) { const [sending, setSending] = useState(false); const send = async () => { setSending(true); try { const res = await fetch(`/api/contract/${contractId}/send-whatsapp`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ phone: recipient }), }); if (!res.ok) throw new Error("Send failed"); alert("Contract sent to WhatsApp"); } catch (e) { alert("Could not send contract"); } finally { setSending(false); } }; return ( <button onClick={send} disabled={sending} className="btn-whatsapp"> {sending ? "Sending…" : "Share via WhatsApp"} </button> ); } 

The component uses a simple POST request; the button is styled with the teal theme introduced in the latest branding update.

Backend Implementation

FastAPI exposes the endpoint in api/contract.py:

from fastapi import APIRouter, HTTPException from sqlalchemy.orm import Session from .models import Contract from .whatsapp import send_pdf_via_whatsapp router = APIRouter() @router.post("/contract/{contract_id}/send-whatsapp") async def send_whatsapp(contract_id: int, payload: dict, db: Session): contract = db.query(Contract).filter(Contract.id == contract_id).first() if not contract: raise HTTPException(status_code=404, detail="Contract not found") phone = payload.get("phone") if not phone: raise HTTPException(status_code=400, detail="Phone number required") # contract.pdf is a byte array stored in PostgreSQL  success = await send_pdf_via_whatsapp(phone, contract.pdf, contract.title) if not success: raise HTTPException(status_code=500, detail="WhatsApp send failed") return {"status": "sent"} 

The helper send_pdf_via_whatsapp wraps the Twilio WhatsApp API:

import aiohttp async def send_pdf_via_whatsapp(to: str, pdf_bytes: bytes, title: str) -> bool: url = "https://api.twilio.com/2010-04-01/Accounts/ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Messages.json" data = { "From": "whatsapp:+14155238886", "To": f"whatsapp:{to}", "Body": f"Here is your {title}.", } files = {"MediaUrl": ("contract.pdf", pdf_bytes, "application/pdf")} auth = aiohttp.BasicAuth("ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "your_auth_token") async with aiohttp.ClientSession(auth=auth) as session: async with session.post(url, data=data, files=files) as resp: return resp.status == 201 

The PDF is streamed directly; no temporary file is written to disk. Good contract generator keeps the rest of the workflow predictable.

UX Considerations

  • The Share via WhatsApp button appears only after the contract is ready, keeping the interface clean.
  • The button uses a 48 px touch target, satisfying the mobile improvements commit.
  • On success, the toast uses the Inter font, aligning with the unified DoAide branding.

Benefits for Indian SMBs

  • Instant delivery: No email attachments, no manual uploads.
  • Higher conversion: Clients receive the contract in their primary messaging app.
  • Compliance: The contract remains a single PDF file, preserving formatting for legal review.

Conclusion

By integrating WhatsApp sharing into the contract generation workflow, DoAide Contracts removes a common bottleneck for Indian SMB owners. The implementation demonstrates how a lightweight FastAPI endpoint and a React button can leverage an external API to deliver a seamless user experience.

Further Reading

  • The project’s blog now contains a post on WhatsApp contract sharing.
  • The new SEO‑friendly blog posts include structured data for better discoverability.

Code Repository

All changes are available in the latest commit on GitHub: https://github.com/r2st/DoAide-Contracts/commit/9778d074b8bea1329eaed78e12438e9b496de2ed

Related reading