Railway에서 FastAPI·Stripe·x402·MCP 하나의 스택으로 다중 제품 AI API 비즈니스 구축 방법

발행: (2026년 6월 6일 AM 02:49 GMT+9)
9 분 소요
원문: Dev.to

출처: Dev.to

몇 달 전, 내가 만든 AI 도구—수동 소득 분석기, AI 전략 컨설턴트, 자율 상거래 레이어—에 대한 접근 권한을 판매하고 싶었다. 일반적인 접근 방식은 SaaS 플랫폼을 골라 수수료를 내고, 그들의 제한을 받아들이는 것이다.
하지만 나는 ACE를 만들었다—모든 것을 스스로 처리하는 AI 상거래 엔진. 몇 달째 Railway에서 실행 중이며, 라이선스 키를 제공하고 Stripe 웹훅을 처리하며 x402 마이크로페이먼트를 받아들인다. 아래가 아키텍처다.

ACE는 결제 이벤트와 AI 도구 전달 사이에 위치하는 라이선스 서버다. 누군가 결제하면:

  1. Stripe가 웹훅을 발송한다
  2. ACE가 이벤트를 검증한다
  3. ACE가 구매한 제품에 한정된 Fernet 암호화 라이선스 키를 생성한다
  4. Resend가 이메일로 키를 전달한다
  5. 고객은 키를 사용해 API를 호출한다

현재 세 가지 제품을 제공한다:

  • YIELD INTELLIGENCE — 수동 소득 기회 스캐너 (국채 금리, 배당 스크리닝, AI 분석 패스)
  • COUNSELOR — AI 인프라 전략 및 아키텍처 컨설팅
  • ACE Autonomous Commerce — 에이전트 간 구매 실행 및 지출 한도 적용

세 제품 모두 MCP‑native (Streamable HTTP, spec 2025‑11‑25)이며 에이전트 카드로 A2A‑discoverable하다.

FastAPI (Python)
├── Stripe webhook handler (payment → license)
├── License generation (Fernet encryption)
├── Resend email delivery
├── SQLite WAL (license tracking, idempotency guards)
├── x402 middleware (micropayment route protection)
└── MCP server wrapper (tools/call interface)

Railway에 배포됨. 현재 규모에서 비용: $0/월 (Railway 무료 티어가 트래픽이 늘 때까지 커버).

ACE는 두 가지 결제 방식을 지원한다. 고객이 인간이든 에이전트이든 모두에게 맞추기 위해서다.

  • Stripe는 인간 구독 결제를 담당한다. 월별 티어에 따라 Stripe 웹훅이 라이선스 키 생성을 트리거한다. 웹훅 핸들러는 멱등성을 보장한다—SQLite 중복 검사로 재발행을 방지한다.
  • x402는 에이전트‑대‑에이전트 마이크로페이먼트를 담당한다. 보호된 엔드포인트를 결제 없이 호출하면 ACE는 HTTP 402와 USDC 결제 챌린지를 반환한다. 에이전트는 Base 메인넷에서 결제하고 X-PAYMENT 헤더와 함께 재시도하면, ACE가 온체인 정산을 검증한 뒤 응답을 제공한다.

이 구분이 중요한 이유: 인간은 월 구독, 에이전트는 호출당 결제. 동일 API, 두 개의 결제 레일.

from cryptography.fernet import Fernet

# Key generation (on webhook)
fernet = Fernet(FERNET_KEY)
license_key = fernet.encrypt(
    json.dumps({
        "product": "yield_intelligence",
        "tier": "professional",
        "customer_id": stripe_customer_id,
        "issued_at": datetime.utcnow().isoformat(),
        "expires_at": (datetime.utcnow() + timedelta(days=30)).isoformat(),
    }).encode()
).decode()

키 자체가 페이로드다. 별도의 조회 테이블이 없으며—복호화가 바로 검증이다. Fernet 복호화가 성공하고 만료 시간이 지나지 않았다면 키는 유효하다.

SQLite WAL이 멱등성을 담당한다:

# Before issuing any key
cursor.execute(
    "SELECT license_key FROM licenses WHERE stripe_payment_intent = ?",
    (payment_intent_id,)
)
if cursor.fetchone():
    return existing_key  # replay protection

각 제품은 MCP 도구로 노출된다. 래퍼는 최소한이다:

@app.post("/mcp")
async def mcp_endpoint(request: MCPRequest, api_key: str = Depends(validate_key)):
    if request.method == "tools/list":
        return {"tools": TOOLS_SCHEMA}

    if request.method == "tools/call":
        tool_name = request.params["name"]
        arguments = request.params["arguments"]

        result = await TOOL_HANDLERS[tool_name](arguments)
        return {"content": [{"type": "text", "text": json.dumps(result)}]}

A2A 에이전트 카드는 /.well-known/agent.json에 존재하며, 가격 매니페스트, 지원 프로토콜, 기능 설명을 담고 있다. 다른 에이전트는 ACE를 발견하고, 가격을 조회한 뒤 호출 여부를 결정한다—결제가 이루어지기 전 단계이다.

ACE의 AI 제품은 Claude를 추론 레이어로 사용하지만, 비용 구조는 고객에게 그대로 전달한다. BYOK (Bring Your Own Key): 고객이 자신의 Anthropic API 키를 제공하면 ACE가 그 키를 분석 호출에 사용하고 결과를 반환한다.

따라서 ACE의 AI 호출에 대한 한계 비용은 0이다. 라이선스 요금이 인프라와 IP(프롬프트, 데이터 파이프라인, AI 호출 주변 비즈니스 로직)를 커버한다—컴퓨팅 비용은 아니다.

# Customer's key is scoped to their request context
async def analyze_yield_opportunities(args: dict, customer_key: str):
    client = AsyncAnthropic(api_key=customer_key)
    response = await client.messages.create(
        model="claude-opus-4-7",
        messages=[{
            "role": "user",
            "content": build_yield_analysis_prompt(args, live_rates)
        }]
    )
    return parse_analysis_response(response)

Railway용 Dockerfile:

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Railway 환경 변수(STRIPE_SECRET_KEY, FERNET_KEY, RESEND_API_KEY 등)는 레포에 비밀이 전혀 없다.

Railway의 자동 배포는 푸시만 하면 약 2분 안에 재배포된다. 이 규모에서는 GitHub Actions 설정이 필요 없다.

SQLite는 충분히 잘 동작하지만, 트래픽 급증 시 쓰기 경쟁이 발생한다. 마이그레이션 경로는 Postgres이며—Railway에서는 환경 변수 하나만 바꾸면 된다—하지만 실제 부하가 생길 때까지는 미루고 있다.

x402 미들웨어는 오류 메시지를 개선할 필요가 있다. 현재 잘못된 결제 헤더는 일반적인 402만 반환한다. 어떤 필드가 잘못됐는지, 올바른 형식은 무엇인지 알려주는 구조화된 오류 본문을 추가하면 에이전트 개발자가 디버깅하는 시간을 크게 줄일 수 있다.

모니터링은 얇다. 헬스 체크와 Railway 내장 메트릭만 있다. 구조화된 로그 → 쿼리 가능한 로그 스토어 형태의 관측 레이어를 구축하면 프로덕션 이슈를 더 빠르게 디버깅할 수 있다. 현재는 Railway 로그와 grep 정도다.

ACE는 현재 운영 중이다. 라이선스 전달이 자동화돼 있고, 엔드포인트는 MCP‑native이며 A2A‑discoverable다. 매출은 아직 적지만(초기 단계) 아키텍처는 내 개입 없이도 동작한다.

다음 목표는 트래픽 확보—이 도구가 필요한 에이전트 개발자들이 MCP 레지스트리, 모델 마켓플레이스, 이와 같은 dev.to 글 등에서 ACE를 찾게 만드는 것이다.

수동 소득 분석, AI 아키텍처 전략, 혹은 에이전트 스택에 자율 상거래 레이어가 필요하다면—ACE는 ace-license-server-production.up.railway.app에서 이용할 수 있다.

Built by ~K¹ (William Kyle Million) · IntuiTek¹

0 조회
Back to Blog

관련 글

더 보기 »

모바일 한여름 열풍

!Cover image for Mobile Midsommer Madnesshttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploa...