Skip to content

Support deferred PaymentIntent outcomes - #46

Merged
midagedev merged 1 commit into
mainfrom
payment-intent-deferred-outcomes
May 11, 2026
Merged

Support deferred PaymentIntent outcomes#46
midagedev merged 1 commit into
mainfrom
payment-intent-deferred-outcomes

Conversation

@midagedev

Copy link
Copy Markdown
Owner

Summary

  • persist PaymentIntent metadata and expose it in Stripe-like responses
  • allow one-time PaymentIntents to store a deferred outcome through metadata or local aliases, then apply it on confirm
  • add Billtap-only POST /api/payment_intents/{id}/outcome for test orchestration

Verification

  • go test ./internal/api -run TestDirectPaymentIntentAndSetupIntentStateMachines
  • go test ./internal/api ./internal/storage ./internal/fixtures ./internal/stripecompat
  • go test ./...
  • go run ./cmd/billtap compatibility scorecard --output-dir /tmp/billtap-compatibility-payment-intent-outcomes
  • git diff --check
  • forbidden keyword scan

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE

개요

이 PR은 일회성 PaymentIntent에 대해 deferred outcome 설정 기능을 추가합니다.
metadata[billtap_payment_intent_outcome], billtap_outcome, deferred_outcome,
payment_intent_outcome 중 하나를 통해 생성 시점에 outcome을 저장하고, confirm 시점에
적용합니다. 또한 테스트 오케스트레이션을 위한 POST /api/payment_intents/{id}/outcome
엔드포인트를 추가합니다.

주요 변경사항

  1. Migration 013: payment_intents 테이블에 metadata 컬럼 추가
  2. Billing models: PaymentIntent 구조체에 Metadata 필드 및 MetadataPaymentIntentOutcome 상수 추가
  3. Billing service:
    • CreatePaymentIntent: deferred outcome 유효성 검사 추가
    • ConfirmPaymentIntent: 저장된 deferred outcome 적용 로직
    • SetPaymentIntentOutcome: 새로운 outcome 설정 메서드
  4. Storage: 모든 PaymentIntent CRUD 작업에 metadata 처리 추가
  5. API:
    • 새로운 /api/payment_intents/{id}/outcome 엔드포인트
    • PaymentIntent 생성/confirm 시 deferred outcome 처리
    • PaymentIntent 응답에 metadata 포함

검증 결과

✅ Billing State Correctness

  • Migration 013
  • service.go:
    CreatePaymentIntent에서 outcome 유효성을 검사하고, ConfirmPaymentIntent에서
    paymentIntentConfiguredOutcome를 통해 저장된 outcome을 올바르게 적용합니다.
  • Timeline 엔트리에 outcome 정보가 포함되어 상태 추적이 가능합니다.

✅ Webhook Reliability

  • 기존 webhook 시맨틱을 변경하지 않습니다.
  • Timeline 엔트리에 outcome 필드가 추가되지만, 이는 디버깅 정보를 보강하는 것입니다.
  • signature, retry, duplicate, delay, out-of-order 처리에 영향이 없습니다.

✅ Safety

  • 실제 카드 데이터 또는 production payment credential을 처리하지 않습니다.
  • 이 기능은 오직 테스트/sandbox 환경에서의 deterministic outcome 제어용입니다.
  • 새로운 /api/payment_intents/{id}/outcome 엔드포인트는 docs/COMPATIBILITY.md에서
    Billtap-only로 명확히 문서화되어 있습니다.
  • paymentIntentConfiguredOutcome 함수는 MetadataPaymentIntentOutcomebilltap_outcome
    키만 확인하여 중복을 방지합니다.

✅ Scenario/Fixture Contract

  • api_test.go:
    metadata를 통한 deferred decline과 /api/payment_intents/{id}/outcome 엔드포인트를 통한
    deferred SCA 시나리오를 모두 커버하는 테스트가 추가되었습니다.
  • storage_test.go:
    migration 테스트가 13개 migration으로 업데이트되었고, metadata persistence가 검증됩니다.

✅ UI/API Coherence

  • 이 변경은 순수 backend API 변경입니다. UI/UX에 영향이 없습니다.
  • stripePaymentIntent 함수에서
    metadata를 응답에 포함하도록 업데이트되어 Stripe-like API와 일치합니다.

✅ Documentation

✅ Validation

  • validation.go:
    confirm=true일 때 payment_method가 없지만 deferred outcome이 있는 경우를 올바르게
    처리합니다 (hasPaymentIntentDeferredOutcome 함수).

제안 사항 (Suggestion)

사소: outcome key 중복 처리

paymentIntentMetadata
함수는 metadata[billtap_payment_intent_outcome], billtap_outcome, deferred_outcome,
payment_intent_outcome 등 여러 키를 허용합니다. firstNonEmptyString으로 우선순위를
두지만, 사용자가 여러 키를 동시에 전달할 경우 혼란스러울 수 있습니다. 그러나 이는 이미
paymentIntentMetadata 함수에서 정규화되므로 기능적 문제는 없습니다. 향후 사용자 가이드에서
권장 키(metadata[billtap_payment_intent_outcome])를 명확히 하면 좋습니다.

결론

Blocking issue가 없습니다. Billing state correctness, webhook reliability, safety,
scenario contract, documentation 관점에서 모두 적절하게 구현되었습니다. 테스트 커버리지가
충가되었고, Stripe-like API와의 일관성이 유지됩니다.

Reviewed by Z.ai GLM via Claude Code Action

@midagedev
midagedev merged commit f773b18 into main May 11, 2026
3 checks passed
@midagedev
midagedev deleted the payment-intent-deferred-outcomes branch May 11, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant