Case Study / Healthcare SaaSRecetasMedicas · Nordic Med S.L. · Spain

Digital Health Platform Development

End-to-end prescription platform for private clinics — from patient intake to signed e-prescription

We designed and built RecetasMedicas: a full-stack SaaS platform that takes a patient from online form submission through biometric identity verification, Stripe payment, and into Spain's national REMPe e-prescription registry — fully automated, in three languages.

RecetasMedicas patient-facing homepage — get fast treatment from doctors online

Integrations

4

Stripe, WebDoc, REMPe, SMTP

Languages

3

Spanish · English · Swedish

Pipeline steps

7+

Automated post-payment

Environments

2

Live + dev, fully isolated

Direct answer

RecetasMedicas is a full-stack healthcare SaaS platform that takes a patient from an online form through Stripe Identity biometric verification and payment into Spain's national REMPe e-prescription registry, with automated WebDoc EHR record creation — fully automated, in three languages.

Audience: Healthcare founders, clinic operators, and engineers evaluating e-prescription or EHR integrationsRegion: SpainIntent: informational

Private clinics in Spain had no connected digital path from consultation to prescription

Nordic Med S.L., a private medical clinic operator in Spain, was managing patient intake on paper, sending prescriptions manually, and reconciling billing and clinical records across disconnected systems. Each patient visit required staff to re-enter data into WebDoc (their EHR), initiate prescriptions separately via REMPe, and chase patients for payment.

Beyond the operational cost, the process created compliance risks. Spain's REMPe system — the national private e-prescription registry operated by Digital Prescription Services (DPS) — requires precise citizen identification data, professional registration, and signed session tokens. Errors in any of these fields mean a prescription cannot be issued.

The clinic needed a single digital path: patient fills a form online, verifies their identity biometrically, pays, and receives their prescription — with all data flowing automatically into WebDoc and REMPe. No re-entry, no gaps, no manual hand-off.

A modular platform that connects patient intake, payment, identity, EHR, and e-prescription in a single automated flow

We built RecetasMedicas as a Next.js monorepo with three distinct surfaces: a patient-facing application (forms, payment, portal), an embeddable SDK for clinic websites, and a comprehensive admin panel. These connect outward to four external systems via a post-payment orchestration pipeline that runs automatically after every successful order.

RecetasMedicas patient portal dashboard — orders, documents, and messages

The system handles everything a clinic used to do manually — from reading a passport scan to creating a signed prescription in Spain's national registry — in under two minutes per patient.

Embeddable Clinic SDK

A single UMD JavaScript bundle (medforms-sdk.umd.js) that any clinic can drop into their existing website with one script tag. It fetches form schemas at runtime, renders dynamic forms, handles the full payment and identity flow, and shows real-time order status — zero clinic-side configuration.

Dynamic Form Generation

Forms are entirely schema-driven: field types, validation, conditional branching, and multi-language labels are configured in the admin panel and served as JSON. Clinics publish or modify consultation forms without a code deployment. Answers are encrypted at rest with rotating data keys.

Stripe Payment Integration

Full Stripe PaymentElement integration with webhook-verified payment confirmation. Supports deferred payment (submit now, pay later from the portal). Card failures are handled at SDK level without a webhook dependency.

Stripe Identity Verification

Biometric passport and national ID scanning with live-capture required (no static uploads). A webhook triggers immediate evidence capture — verified name, DOB, document number, type, and issuing country — with a scheduled fallback re-fetching evidence inside the 48-hour availability window.

WebDoc EHR Integration

Automated patient record management in WebDoc (Atlan). The orchestrator creates or updates a patient record, pushes a clinical record, creates a booking, logs the visit, generates an invoice, and uploads the consultation document — all from one form submission.

REMPe E-Prescription Integration

Spain's national private e-prescription system, integrated via SOAP/WSDL. Creates an authenticated doctor session, opens a secure prescription iframe, then retrieves the signed prescription PDF using the patient's citizen identification. Supports DNI, NIE, PASAPORTE, and CIP.

Admin Orchestration Pipeline

A post-payment pipeline runs every order through: WebDoc patient push → REMPe session creation → prescription delivery queue → email notification. Each step is tracked individually with its own status, error log, and manual retry.

Scheduled Task System

A task runner executes every minute in production across five queues: portal credentials, prescription delivery email, WebDoc document push, REMPe status polling (24h window), and Stripe Identity evidence capture (48h window).

Multi-Language Support

Full internationalisation across Spanish, English, and Swedish — UI, form labels, validation messages, email templates, and legal pages. Language is detected from URL locale with a switchable interface; the admin panel runs in English.

Document Security

Form answers encrypted at rest with AES and rotating data keys — key IDs stored alongside ciphertext so rotation is non-destructive. Sensitive identity fields require admin staff to re-enter their password before being revealed, with a timed re-lock.

Customer Self-Service Portal

A post-purchase portal accessible via magic link or credentials, where patients view order history, track prescription delivery, download signed PDFs, update their details, and view verification status.

Isolated Live & Dev Environments

Two fully independent environments sharing no infrastructure: separate databases, separate Stripe accounts, separate REMPe endpoints, separate domains, separate PM2 process groups — enforced by the deploy script on every deployment.

A Next.js monorepo built for independent scaling of patient-facing, admin, and SDK surfaces

The platform is a pnpm workspace monorepo with three deployable applications and two shared packages. The patient portal and admin panel use Next.js 15 (App Router) with Server Components for data-heavy views. PostgreSQL with Prisma ORM underpins all persistence.

RecetasMedicas admin panel — clinic orders, WebDoc sync status, and operations controls

Applications

core-api — Patient portal & forms
admin — Clinic management panel
SDK — Embeddable UMD bundle

Persistence & Runtime

PostgreSQL + Prisma ORM
Node.js 24 / PM2
Apache reverse proxy
Let's Encrypt TLS

External Systems

Stripe Payments + Identity
WebDoc / Atlan EHR (REST)
REMPe (SOAP / WSDL)
SMTP — Hostinger / Nodemailer

Two integrations that required precision work: REMPe and Stripe Identity

Most of the project's technical complexity sits inside two integrations that have no simple drop-in SDK — they required reading WSDL specifications, reverse-engineering expand parameter behaviour, and building robust fallback systems around API windows that close after 48 hours.

REMPe — Spain's National Private E-Prescription System

Operated by Digital Prescription Services S.A. (DPS) · Production-only

SOAP / WSDL

REMPe is the Spanish Ministry of Health's private e-prescription registry. Every prescription issued by a private clinic in Spain must pass through this system. Integration requires three separate WSDL endpoints, clinic establishment codes (UUID), professional registration confirmation, and precise citizen identification — any mismatch causes the entire session to be rejected with an opaque error code.

We implemented a full SOAP client covering the EHRCitizenIdentificationv2 (session creation), EHRTreatmentQueryv2 (prescription listing), and EHRTreatmentReportQueryv3 (PDF retrieval) specifications. The citizen identification flow sends the patient's verified identity data — obtained from Stripe Identity — directly into the REMPe session, so the document number and type REMPe receives matches exactly what was scanned. Error codes are parsed from the XML <Result> tag and surfaced as human-readable messages in the admin panel.

  • EHRCitizenIntegrationv2 WSDL
  • EHRTreatmentQueryv2 WSDL
  • EHRTreatmentReportQueryv3 WSDL
  • UUID establishment identification
  • DNI / NIE / PASAPORTE / CIP support
  • Prescription PDF retrieval
  • Delegated access via secure iframe
  • 24-hour polling window with task runner

Stripe Identity — Biometric Document Verification with Evidence Capture

Live capture · 48-hour evidence window · Webhook + scheduled fallback

REST / Webhook

Stripe Identity verifies patient identity by scanning a passport or national ID through the device camera. The critical design challenge: Stripe's verification report — containing the extracted name, DOB, and document number — is only accessible for 48 hours after the session is verified. Beyond that window, the data is redacted and permanently unavailable.

We implemented a two-layer capture strategy: a webhook handler that processes identity.verification_session.verified events immediately, fetching the full report with explicit expand parameters (last_verification_report.document.dob, last_verification_report.document.number) to un-redact sensitive fields — and a scheduled task running every minute for the first 47 hours as a safety net for missed or delayed webhooks. Captured evidence feeds directly into REMPe citizen identification.

  • Live capture (no static uploads)
  • Webhook event handling
  • Expand param evidence extraction
  • Name / DOB / document number
  • Document type normalisation
  • Issuing country extraction
  • 48-hour scheduled fallback task
  • Admin password-gated reveal

WebDoc / Atlan EHR — Full Patient Record Automation

OAuth 2.0 client credentials · Swedish EHR platform

REST / OAuth

WebDoc (marketed as Atlan) is the EHR system used by the Nordic private clinic network. Rather than requiring staff to manually create patient records after each online consultation, the orchestration pipeline handles the full clinical record lifecycle automatically: it looks up or creates a patient record, pushes an external clinical record with consultation notes, creates a booking entry, logs the visit, records an invoice, and uploads the completed consultation document as a PDF attachment.

  • Patient lookup / creation
  • External clinical record push
  • Booking creation
  • Visit record entry
  • Invoice generation
  • Document upload & verification
  • OAuth client credentials flow
  • Clinic-scoped API isolation

Healthcare data demands more than HTTPS

Medical platforms handle some of the most sensitive personal data in existence — passport numbers, dates of birth, health conditions, prescription details. We applied layered security controls across storage, access, and transmission.

Encrypted form answers

Patient form responses are encrypted at rest with AES using rotating data keys. Key IDs are stored with ciphertext so keys can be rotated without data loss. Key material never touches the application logs.

Identity data access control

Passport scans, dates of birth, and document numbers are stored with a separate access level. Admin staff must re-enter their password before sensitive identity fields are revealed, with automatic re-lock after the session expires.

Webhook signature verification

All inbound webhooks — Stripe payment, Stripe Identity — are verified against their HMAC signatures before processing. Invalid or replayed events are rejected at the transport layer.

Isolated environments

Live and development share no infrastructure: separate databases, separate Stripe accounts, separate REMPe endpoints. The deploy script enforces environment file reconciliation on every deployment.

TLS everywhere

All customer-facing domains use Let's Encrypt TLS with automatic renewal. Apache redirects HTTP to HTTPS. Internal service-to-service traffic runs through localhost with firewall rules blocking external port access.

Admin authentication

The admin panel uses claims-based auth with scrypt-hashed passwords and short-lived session tokens. API routes are protected by both session cookies and an API key header.

Modern, maintainable, production-tested

The stack was chosen for long-term maintainability: a monorepo structure that scales to additional clinic portals, a typed ORM that prevents schema drift, and a deployment model simple enough for a small team to operate without a dedicated DevOps function.

TypeScript covers the entire codebase, from database schema definitions to SDK build. No runtime type surprises, no environment-specific behaviour divergence between local and production.

Framework & Language

Next.js 15TypeScriptApp RouterServer Componentspnpm Monorepo

Data & Auth

PostgreSQLPrisma ORMscrypt password hashingAES encryption

Integrations

Stripe PaymentsStripe IdentityREMPe (SOAP)WebDoc / AtlanNodemailer / SMTP

Deployment

PM2ApacheOVH VPSNode.js 24Let's Encrypt

From paper forms and manual prescriptions to a fully automated digital clinic workflow

RecetasMedicas replaced a multi-step manual process with an end-to-end digital workflow that runs in real time. Staff no longer re-enter patient data, reconcile payment records, or manually initiate REMPe sessions — the platform handles all of it automatically from the moment a patient submits a form.

Eliminated manual data re-entry

Patient details flow directly into WebDoc and REMPe via the orchestration pipeline. No copy-paste, no transcription errors, no staff time spent moving data between systems.

Passport-level patient identity

Every patient is biometrically verified before their prescription is issued. Verified name, DOB, and document number feed directly into REMPe's citizen identification, satisfying its strict matching requirements.

Real-time prescription delivery

From form submission to signed prescription PDF in the patient's inbox — the entire process runs automatically within minutes of payment, with no clinician or admin touching a keyboard.

Multi-clinic, multi-language deployment

The embeddable SDK lets any clinic website integrate the complete patient flow with a single script tag. Spanish, English, and Swedish patients all get a fully localised experience with no separate deployments.

Technical questions about this project

What is REMPe and why is it difficult to integrate?

REMPe (Receta Médica Privada Electrónica) is Spain's national private e-prescription registry, operated by Digital Prescription Services S.A. (DPS) on behalf of the Spanish Ministry of Health. Integration requires SOAP/WSDL calls — not a REST API — with exact citizen identification data, professional registration confirmation, and establishment UUIDs. Any mismatch causes a session rejection with error codes that must be parsed from raw XML, and the system does not allow fictional professionals in production, meaning the prescribing doctor must be individually registered with DPS before any prescriptions can be issued.

How does Stripe Identity work in the patient flow?

When a patient reaches identity verification, Stripe Identity opens a camera-based scanning flow on their device — no file uploads, live capture only. The patient photographs their passport or national ID; Stripe's OCR and biometric systems verify the document and extract key fields. After verification, our platform receives an identity.verification_session.verified webhook and calls the Stripe API with expand parameters to retrieve the full evidence including DOB and document number, which is then stored and passed to REMPe for citizen identification.

How does the embeddable SDK work?

The SDK (medforms-sdk.umd.js) is a self-contained UMD bundle served from the API domain. Clinics include a single script tag and initialise it with a form identifier. The SDK fetches the form schema at runtime, renders the dynamic form, handles the Stripe payment flow, manages the Stripe Identity session, and shows real-time order status — all within the clinic's own website, styled to match their brand, with no backend setup required beyond the script tag.

How is patient data encrypted and stored?

Form answers are encrypted at rest using AES symmetric encryption with data keys managed in the environment configuration. Each key has an identifier stored alongside the ciphertext, enabling key rotation without data loss. Identity evidence is stored in a JSON column and protected at the application layer with a password re-verification requirement before sensitive fields are displayed. All database traffic is TLS-encrypted and the database port is not exposed externally.

Can this platform be adapted for clinics in other countries?

Yes. The REMPe integration is specific to Spain's private e-prescription system, but the rest of the platform — dynamic forms, Stripe payments, Stripe Identity, EHR push, customer portal, admin panel, and embeddable SDK — is country-agnostic. REMPe could be replaced by another country's e-prescription API, or disabled entirely for clinics using a different prescribing workflow. The multi-language architecture already supports adding new locales without code changes.

What does the WebDoc integration actually create?

After a successful payment, the orchestrator calls WebDoc/Atlan in sequence: patient lookup or creation, external clinical record push with consultation notes, booking creation, visit record entry, invoice generation against the correct payment method, and clinical document upload as a PDF attachment. Clinic staff see the patient's complete EHR entry with no manual data entry required.

How long does development of a platform like this take?

A platform of this scope — four external integrations, two user-facing applications, an embeddable SDK, a scheduled task system, and multi-language support — typically requires four to six months of focused development. The SOAP-based REMPe integration, Stripe Identity evidence capture logic, and orchestration pipeline are the longest lead-time items, since they involve regulatory systems with limited documentation and production-only behaviour that can't be fully tested in sandbox.

Building a healthcare platform, clinic tool, or regulated integration?

We work with founders and operators who need software built properly — compliant, integrated, and production-ready from day one.

Start a conversation