Stripe용 증거 PDF를 포함한 자동 이의제기 응답 시스템
Wikiprompt, 무료 프롬프트 백과사전에서
Stripe용 증거 PDF를 포함한 자동 이의제기 응답 시스템 자동화된 Stripe 차지백 분쟁 시스템을 위한 전체 빌드 스펙: 웹훅 자동 제출, 제품 스크린샷이 포함된 증거 PDF, CLI 동기화 워커, 그리고 미니 관리자 대시보드.
관련 미디어
프롬프트 내용저장
🌐
Stripe 자동 분쟁 대응 시스템 구축:
1. 공유 증거 수집 (app/dispute_evidence.php)
웹훅과 동기화 워커가 모두 사용하는 공유 파일을 생성합니다. 증거 로직의 중복을 피할 수 있습니다.
핵심 함수:
- getDisputeUserPlan($user, $stripe) - Stripe API에서 사용자의 구독 플랜을 가져옵니다 (로컬 DB 플랜 필드는 취소 시 지워지므로 신뢰할 수 있는 출처). Stripe 호출이 실패하면 로컬 DB 필드로 대체합니다. 제품 ID를 플랜 이름에 매핑하고 가격/간격 및 취소 상태를 포함합니다.
- collectDisputeEvidence($stripe, $user, $email, $charge, $photosDb) - 모든 텍스트 및 파일 증거를 수집하고 Stripe에 제출할 준비가 된 배열을 반환합니다.
- generateServiceDocPdf($stripe, $user, $email, $photos_done, $recent_photos, $total_amount_paid) - 고객 정보, 사용 요약, 최근 활동 테이블 및 최대 6개의 실제 제품 이미지(Stripe의 5MB 파일 업로드 제한을 준수하기 위해 500px 너비 / 품질 75의 JPEG로 크기 조정)가 포함된 PDF를 생성합니다. Stripe 파일 ID와 원시 PDF 데이터를 모두 반환합니다.
중요: 로컬 DB(널/오래된 값일 수 있음)를 신뢰하는 대신 Stripe charges API에서 total_amount_paid를 가져옵니다 (성공하고 환불되지 않은 청구의 합계).
2. 웹훅 핸들러 (stripe_webhook.php)
charge.dispute.created 이벤트를 캐치합니다. 분쟁이 발생하면:
- Stripe에서 분쟁, 청구 및 고객 객체를 가져옵니다
- stripe_customer_id로 로컬 데이터베이스에서 사용자를 조회합니다
- 분쟁을 disputes SQLite 데이터베이스에 저장합니다 (필드: dispute_id, charge_id, payment_intent_id, stripe_customer_id, user_id, email, amount, currency, reason, status, epoch_created, epoch_evidence_submitted, evidence_json, stripe_response, epoch_resolved, outcome)
- collectDisputeEvidence()를 호출하여 모든 증거(텍스트 + 파일 업로드)를 수집합니다
- $stripe->disputes->update($dispute_id, ['evidence' => $evidence])를 통해 Stripe에 증거를 제출합니다
- 새 분쟁이 들어왔고 증거가 자동 제출되었음을 알리는 Telegram 알림을 보냅니다
또한 charge.dispute.updated 및 charge.dispute.closed 이벤트를 캐치하여 데이터베이스에서 분쟁 결과(승/패)를 추적하고 결과와 함께 Telegram 알림을 보냅니다.
3. Stripe에 제출되는 증거 필드
텍스트 필드 (문자열 직접 작성):
- product_description - 제품/서비스가 무엇인지 설명
- customer_name / customer_email_address - Stripe 고객 객체에서 가져옴
- access_activity_log - 상세 사용 로그: 가입 날짜, 완료된 항목/작업 수, 마지막 활동 날짜, 구독 플랜(Stripe에서), 플랫폼, 총 결제 금액(Stripe에서), 타임스탬프가 포함된 최근 활동
- uncategorized_text - "우리가 이겨야 하는 이유" 주장: 고객이 X에 가입했고, Y 작업을 수행하며 서비스를 적극적으로 사용했으며, 총 결제 금액, 서비스가 디지털/즉시 전달되었고, 고객이 분쟁 전에 환불을 요청한 적이 없음
- refund_policy_disclosure / cancellation_policy_disclosure - 정책이 제시된 시기(체크아웃 중, /legal에서 항상 접근 가능)
- refund_refusal_explanation / cancellation_rebuttal - 사용 증거 및 사전 연락 부재
- service_date - 청구 날짜 (Y-m-d 형식)
파일 업로드 필드 (먼저 $stripe->files->create(['purpose'=>'dispute_evidence', 'file'=>fopen($path,'r')])를 통해 Stripe에 파일을 업로드한 다음 반환된 file_xxxxx ID를 전달):
- receipt - Stripe에서 인보이스 PDF를 직접 가져옵니다 ($stripe->invoices->retrieve($charge->invoice)->invoice_pdf), 다운로드하여 분쟁 증거로 업로드
- service_documentation - 고객 정보 섹션, 서비스 사용 요약, 최근 활동 테이블 및 고객이 받은 최대 6개의 실제 제품 이미지/스크린샷이 포함된 PDF를 생성합니다. 포함 전에 이미지 크기를 조정합니다(500px 너비, JPEG 품질 75) - Stripe의 5MB 제한을 준수하기 위해.
또한 두 PDF를 해시된 파일 이름으로 파일 저장소(예: Cloudflare R2, S3)에 저장하여 추측할 수 없지만 관리자 대시보드에서 볼 수 있도록 합니다. evidence_json에 _receipt_r2_url 및 _service_doc_r2_url로 저장소 URL을 저장합니다.
4. CLI 동기화 워커 (workers/syncDisputes.php)
Stripe API에서 모든 기존 분쟁을 가져오는 스크립트($stripe->disputes->all(['limit' => 100]) 및 페이지네이션을 위한 starting_after 사용), 로컬 분쟁 데이터베이스에 저장하고, 아직 needs_response 또는 warning_needs_response 상태이고 증거가 아직 제출되지 않은 분쟁에 대해 공유 collectDisputeEvidence() 함수를 사용하여 증거를 자동 제출합니다. 웹훅은 향후 분쟁만 캐치하고 기존 분쟁은 캐치하지 않기 때문에 필요합니다. CLI에서만 실행합니다 (php workers/syncDisputes.php). 대시보드가 마지막 동기화 시간을 표시할 수 있도록 동기화 결과가 포함된 JSON 캐시 파일을 저장합니다.
5. 미니 대시보드 (disputes.php with ?key= 인증)
?key= 쿼리 매개변수로 보호되는 간단한 HTML 페이지로 다음을 표시합니다:
- 통계 상자: 총 분쟁, 대기 중, 승, 패, 최근 30일 분쟁(금액 + 수), 최근 12개월 분쟁(금액 + 수), 총 분쟁 금액
- CLI 동기화 명령 및 캐시의 마지막 동기화 시간을 보여주는 메모
- stripe_customer_id를 입력하여 제출될 증거를 미리 볼 수 있는 테스트 양식(실제 제출 없이)
- 모든 분쟁 테이블: 날짜, 이메일, 금액, 사유, 상태(색상 코드 배지), 증거 제출 상태, 상세 보기 및 Stripe 대시보드 링크
상세 보기(action=view&id=dispute_id): 모든 분쟁 정보, Stripe 링크, "증거 재생성" 버튼, PDF 파일 링크, Stripe 파일 업로드 ID, 모든 텍스트 증거 필드를 표시합니다.
증거 재생성(action=regen&id=dispute_id): 영수증 및 서비스 문서 PDF를 재생성하고 파일 저장소에 업로드하며 evidence_json을 새 PDF URL로 업데이트합니다. fastcgi_finish_request()를 사용하여 HTTP 응답을 즉시 보내고(상세 페이지로 리디렉션하고 "백그라운드에서 재생성 중" 알림 표시), 그런 다음 프런트엔드 시간 초과를 방지하기 위해 백그라운드에서 PDF 생성을 계속합니다.
페이지에 대한 nginx 재작성 규칙을 추가합니다(예: rewrite ^/disputes/?$ /disputes.php). sites-enabled의 심볼릭 링크가 실제로 가리키는 올바른 nginx 구성 파일에 있는지 확인합니다.
6. Telegram 알림
- 새 분쟁: "{사이트 이름} - {이메일}로부터 ${금액} ({사유}) 새 분쟁. 증거가 Stripe에 자동 제출됨. {stripe_dashboard_link}"
- 증거 실패: "{사이트 이름} - {이메일}로부터 ${금액} ({사유}) 새 분쟁. 증거 제출 실패: {오류}"
- 분쟁 승/패 결과 및 링크 포함
- DB 권한 오류: "{사이트 이름} - 분쟁 DB 오류: {오류} - data/disputes.db 권한 확인"
7. Stripe 대시보드에서 다음 웹훅 이벤트가 활성화되어 있는지 확인합니다: charge.dispute.created, charge.dispute.updated, charge.dispute.closed
8. 데이터베이스 권한
disputes.db 파일은 웹 서버 사용자(예: www-data)가 쓸 수 있어야 합니다. CLI에서 root로 생성한 경우 다른 DB 파일과 일치하도록 소유권을 수정합니다. PHP-FPM은 root와 다른 사용자로 실행됩니다.
9. 의존성
- PDF 생성을 위한 FPDF (setasign/fpdf), composer require setasign/fpdf로 설치
- 이미지 크기 조정을 위한 GD 확장(일반적으로 이미 설치됨)
- Stripe PHP SDK(Stripe 웹훅이 있으면 이미 설치됨)
- R2/S3 업로드를 위한 AWS S3 SDK(Cloudflare R2를 사용하는 경우 이미 설치됨)
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 coding와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개