31 KiB
31 KiB
iOS 선물하기 전체 기능 단일 구현 프롬프트
이 문서는 iOS 앱에서 크리에이터 선물하기 사용자 기능을 한 번에 구현할 때 사용하는 단일 프롬프트다. 기존 분할 문서의 사용자 화면 범위를 합치고, Figma UI 확인 결과와 신청 완료 후 상세 이동 정책을 반영했다.
관리자 화면은 iOS 앱 범위가 아니므로 제외한다.
참고 문서
docs/20260929_크리에이터_선물하기/prd.mddocs/20260929_크리에이터_선물하기/client-api-summary.mddocs/20260929_크리에이터_선물하기/gift-send-page-prompt.mddocs/20260929_크리에이터_선물하기/gift-list-page-prompt.mddocs/20260929_크리에이터_선물하기/gift-detail-tracking-page-prompt.mddocs/20260929_크리에이터_선물하기/gift-received-detail-page-prompt.md
Figma 확인 노드
- 선물 보내기: 빈 입력
2481:18904, 입력 완료/CTA 활성2481:18957 - 선물함 리스트: 보낸 내역 있음
2481:19382, 보낸 내역 없음2520:35587, 받은 내역 없음2531:36283, 받은 내역 있음2531:36194, 받은 상태별 카드2531:36237 - 보낸 선물 상세/운송장: 등록 전
2481:19011, 등록 후2481:19152, 전달 완료2481:19320, 전달 불가2481:19456, 취소 다이얼로그2481:19500, 취소 완료2481:19521, 운송장 입력 전2481:19066, 운송장 입력 완료2481:19109 - 받은 선물 상세/배송지: 배송지 입력 전
2531:36290, 배송지 입력 완료2531:36399, 전달 완료2531:36330, 전달 불가2531:36422
Figma 재확인 메모:
- 모든 화면은 iPhone 13 기준 402px 폭, black/dark surface 기반이다.
- 상단 status bar와 nav/top 영역은 고정하고, 본문은
scroll area로 분리한다. - 주요 섹션은 14pt 좌우 여백, 카드/입력/배너는 rounded dark surface, 섹션 사이 divider를 사용한다.
- 선물 보내기 화면은 안내 배너, 받는 크리에이터, 선물 사이즈, 카테고리, 보내는 사람, 약관 동의, 하단 single CTA 구조다.
- 선물함 리스트는 안내 배너와 104pt 높이 카드 리스트 구조다. 실제 구현에서는 Figma에 있는
신청 내역,선물 내역섹션 타이틀을 표시하지 않는다. - 보낸 상세는 상태 hero, 사서함/등록 안내, 선물 정보, 하단 action bar를 중심으로 한다.
- 받은 상세는 상태 hero와 문의 버튼, 선물 정보, 받는 주소 카드 구조를 상태별로 바꾼다.
iOS 구현 프롬프트
iOS 앱의 크리에이터 선물하기 사용자 기능 전체를 Figma와 API 계약 기준으로 구현해줘.
범위:
- 선물 보내기 신청 화면
- 선물함 리스트 화면
- 선물 상세 화면
- 보낸 선물의 운송장 등록 화면
- 보낸 선물의 신청 취소 확인/취소 완료 화면
- 받은 선물의 배송지 입력 UI
- 받은 선물의 배송지 입력 완료/전달 완료/전달 불가 상세 UI
- 푸시/딥링크 진입 시 선물 상세 이동
범위 밖:
- 관리자 화면
- 새 디자인 시스템 생성
- 외부 택배 조회/운송장 실시간 검증
- 약관 본문 제공 API 신규 구현
- 선물 이미지, 첨부파일, 메시지 카드
- 임의 URL 연결
공통 전제:
- iOS 기존 디자인 시스템, 컴포넌트, API client, 인증, 상태 관리, toast/dialog, navigation, loading/error 패턴을 재사용한다.
- Figma visual structure와 문구를 우선 따르되, 데이터 노출과 CTA 조건은 API 계약을 우선한다.
- 모든 API 응답은 공통 envelope를 사용하며 실제 payload는 `response.data` 또는 기존 iOS API client의 data unwrap 결과다.
- 모든 날짜는 UTC ISO 문자열이다. 앱 공통 formatter가 있으면 재사용하고, 상세 필드 날짜는 Figma처럼 `YYYY.MM.DD`로 표시한다.
- 개인정보 노출 경계를 반드시 지킨다. 로그인 회원이 알아야 하는 본인 정보만 표시하고, 상대방의 이름/휴대폰/주소는 표시하지 않는다.
- Figma 기준으로 상단 navigation은 고정하고, navigation 아래 본문만 스크롤한다.
- iOS safe area, keyboard avoidance, bottom action bar는 기존 앱 패턴을 따른다.
- 새 route/deep link가 필요하면 기존 navigation/deep link 등록 방식에 맞춘다.
가장 중요한 이동 정책:
- 선물 보내기 신청 `POST /api/v2/gifts` 성공 시 완료 dialog에서 멈추지 말고, 성공 응답의 `applicationNo`로 선물 상세 페이지로 이동한다.
- 신청 완료 직후 이동 대상은 `GET /api/v2/gifts/{applicationNo}` 기반 상세 페이지다.
- 신청 성공 후 뒤로가기로 입력 폼에 다시 돌아와 중복 신청하지 않도록 기존 iOS navigation 정책에 맞춰 replace 또는 stack 정리를 적용한다.
- 선물함 리스트 item 탭, 푸시 딥링크, 신청 완료 후 이동은 모두 같은 상세 화면으로 들어가고, 상세 API의 `direction`, `trackingRequired`, `recipientAddressRequired`, `status`로 UI를 분기한다.
보낸 사람/받는 사람 상세 차이:
- 같은 `GET /api/v2/gifts/{applicationNo}` 상세 API를 사용하지만 `direction`에 따라 상세 페이지를 다르게 표시한다.
- `direction=SENT`는 보낸 팬 관점이다.
- 받는 크리에이터 닉네임은 `giftInfo.recipientCreatorNickname`으로 표시한다.
- 팬 본인이 신청 시 입력한 발신자 정보 `senderInfo`를 표시할 수 있다.
- 관리자 전역 사서함 `mailbox`가 있으면 `보내실 주소` 또는 `받는 사서함` 섹션에 표시한다.
- 크리에이터가 입력한 배송지 `recipientAddress`는 표시하지 않는다.
- `trackingRequired=true`이면 운송장 등록 CTA를 표시한다.
- `status=RECEIVED`이면 신청 취소 action을 제공할 수 있다.
- `direction=RECEIVED`는 받는 크리에이터 관점이다.
- 보낸 팬 닉네임은 `giftInfo.senderNickname`으로 표시한다.
- 팬이 신청 시 입력한 이름/휴대폰/주소 `senderInfo`는 표시하지 않는다.
- `mailbox`, `giftInfo.applicationNo`, `giftInfo.paidCan`, `giftInfo.tracking`은 표시하지 않는다.
- 크리에이터 본인이 입력한 배송지 `recipientAddress`가 있을 때만 받는 주소 섹션을 표시한다.
- `recipientAddressRequired=true`이면 배송지 입력 UI를 표시한다.
1. 선물 보내기 화면
Figma:
- 빈 입력 상태: `2481:18904`
- 입력 완료/CTA 활성 상태: `2481:18957`
진입 전제:
- 크리에이터 닉네임과 `memberId`를 받아 이 화면으로 이동하는 기존 흐름은 이미 있다.
- 이 작업에서 새 진입 흐름을 만들지 않는다.
- 전달받은 크리에이터 닉네임은 `받는 크리에이터` 영역에 표시한다.
- 전달받은 `memberId`는 `POST /api/v2/gifts`의 `recipientMemberId`로 보낸다.
- 둘 중 하나라도 없으면 기존 앱의 오류 처리 또는 안전한 뒤로가기 패턴을 따른다.
화면 구조:
- 상단 타이틀: `선물 보내기`
- 안내 배너
- 제목: `선물 보내기 베타 서비스 안내`
- 본문: `베타 기간 동안은 일부 기능만 제공됩니다. 크리에이터에게 마음을 잘 전할 수 있도록 더 넓어진 선물 보내기로 곧 다시 만나요!`
- 받는 크리에이터: Figma 프로필 row 형태로 전달받은 닉네임 표시
- 선물 사이즈: `GET /api/v2/gifts/form-options`의 `sizes` 바인딩
- 카테고리: 같은 응답의 `categories` 바인딩
- 보내는 사람 입력: 이름, 휴대폰 번호, 우편번호, 주소, 상세 주소
- 이용 약관 동의: 발송 규정 요약 박스와 체크박스 2개
- 하단 CTA: `{salePriceCan}캔으로 선물 보내기`
폼 옵션 조회:
- 화면 진입 시 `GET /api/v2/gifts/form-options` 호출
- `sizes` 기본 선택은 서버가 내려준 첫 번째 항목
- 가격 표시는 `salePriceCan`을 사용하고 신청 금액도 `salePriceCan`을 사용
- `basePriceCan != salePriceCan`이면 기존 앱 할인/정가 표시 패턴이 있을 때만 정가를 함께 표시
- 사이즈 설명은 API에 없으므로 앱 로컬 매핑 사용
- `SMALL`: `세 변의 합 100cm 이하 · 5kg 이하`
- `MEDIUM`: `세 변의 합 120cm 이하 · 15kg 이하`
- `LARGE`: `세 변의 합 160cm 이하 · 20kg 이하`
- 카테고리 select는 기존 iOS picker/bottom sheet/dialog 패턴 중 앱에서 이미 쓰는 방식을 사용
- `requiresDamageWaiver=true` 카테고리 선택 시에만 파손 면책 동의 row 표시
- `requiresDamageWaiver=false` 선택 시 파손 면책 동의 row를 숨기고 `damageWaiverAgreed=false`로 초기화
입력 필드 매핑:
- 이름 input -> `senderName`
- 휴대폰 번호 input -> `senderPhoneNumber`
- 우편번호 input -> `senderZipCode`
- 주소 input -> `senderAddress`
- 상세 주소 input -> `senderAddressDetail`
- 우편번호 검색은 기존 주소 검색 기능을 재사용한다.
동의 필드:
- `소다라이브 크리에이터 상품 전달 이용약관에 동의합니다. (필수)` -> `senderTermsAgreed`
- `상품 전달을 위한 개인정보 수집·이용에 동의합니다. (필수)` -> `senderPrivacyAgreed`
- `파손 및 분실 면책 사항에 동의합니다. (필수)` -> `damageWaiverAgreed`, 필요한 카테고리에서만 표시/필수
- 각 약관 문구의 `(필수)` 부분은 터치 가능한 링크로 처리한다.
- `(필수)` 터치 시 약관 Notion 웹페이지로 이동한다.
- sender 약관 2개와 recipient 약관 2개는 모두 같은 Notion 페이지로 이동하면 된다.
- Notion 페이지 URL은 실제 구현 시 입력받도록 처리하고, 이 프롬프트에서 임의 URL을 하드코딩하지 않는다.
CTA 활성 조건:
- `memberId` 있음
- 사이즈 선택됨
- 카테고리 선택됨
- 이름, 휴대폰 번호, 우편번호, 주소 입력됨
- 이용약관 동의 true
- 개인정보 동의 true
- 선택 카테고리의 `requiresDamageWaiver=true`이면 파손 면책 동의 true
- submit 중에는 중복 탭 방지와 loading 표시
- validation 실패 시 `POST /api/v2/gifts`를 호출하지 않는다.
선물 신청 API:
- Method: `POST`
- URL: `/api/v2/gifts`
- Request:
```json
{
"recipientMemberId": 100,
"senderName": "김소다",
"senderPhoneNumber": "01000000000",
"senderZipCode": "12345",
"senderAddress": "서울시 강남구 ...",
"senderAddressDetail": "123동 456호",
"sizeCode": "SMALL",
"categoryId": 1,
"senderTermsAgreed": true,
"senderPrivacyAgreed": true,
"damageWaiverAgreed": true
}
- Response data:
{
"applicationNo": "A-1002609300001",
"status": "RECEIVED",
"statusName": "접수 완료",
"priceCan": 80,
"trackingDeadlineAt": "2026-10-02T03:00:00Z"
}
- 성공 시
applicationNo로 선물 상세 페이지로 이동한다. - 실패 시 서버 메시지를 기존 앱 오류 노출 방식으로 표시하고 입력값은 유지한다.
- 선물함 리스트 화면
Figma:
- 보낸 내역 있음:
2481:19382 - 보낸 내역 없음:
2520:35587 - 받은 내역 없음:
2531:36283 - 받은 내역 있음:
2531:36194 - 받은 상태별 카드:
2531:36237
공통 요구사항:
- 상단 타이틀:
선물함 - 상단 뒤로가기 navigation은 고정
- navigation 아래 콘텐츠만 스크롤
- Figma에 보이는
신청 내역,선물 내역섹션 타이틀은 표시하지 않는다. - 리스트는 서버 응답 순서를 우선 사용한다. 현재 API만으로 취소일 기준 재정렬을 임의 구현하지 않는다.
- item 탭 시
applicationNo를 전달해 선물 상세 페이지로 이동한다.
API:
- Method:
GET - URL:
/api/v2/gifts?type=ALL&page=0&size=20 - 이 화면에서는
SENT,RECEIVED를 따로 호출하지 않고type=ALL을 사용한다. items[].direction으로 보낸/받은 카드 UI를 결정한다.hasNext=true이면 스크롤 하단에서 다음 page를 추가 조회한다.- 기존 앱에 pull-to-refresh가 있으면 page 0부터 다시 조회한다.
Response data 예시:
{
"totalCount": 2,
"items": [
{
"applicationNo": "A-1002609300001",
"direction": "SENT",
"status": "RECEIVED",
"statusName": "접수 완료",
"priceCan": 80,
"categoryName": "아크릴/스탠드",
"sizeName": "소형",
"counterpartMemberId": 200,
"counterpartNickname": "달빛수집가",
"counterpartProfileImageUrl": "https://example.com/profile.png",
"recipientAddressRegistered": false,
"recipientAddressDeadlineAt": null,
"canceledAt": null,
"createdAt": "2026-09-18T03:00:00Z"
}
],
"page": 0,
"size": 20,
"hasNext": false
}
보낸 선물 카드 (direction=SENT):
- 상대방은 선물을 받는 크리에이터다.
- 상단 안내 배너 표시
- 제목:
사서함을 통해 안전하게 전달됩니다 - 본문:
크리에이터 및 팬의 주소는 공개되지 않습니다. 선물은 소다라이브 사서함에 도착한 뒤 크리에이터에게 전달됩니다.
- 제목:
- 카드에는
statusName, 날짜 라벨, 크리에이터 프로필/닉네임,sizeName · categoryName, chevron 표시 - 날짜 라벨은 기본
{createdAt} 신청; 취소일 필드가 없으면 임의 취소일 계산 금지 status=CANCELED이고canceledAt이 있으면 날짜 라벨은{canceledAt} 취소로 표시한다.- 보낸 선물 empty는 안내 배너만 표시하고 별도 empty title/body를 추가하지 않는다.
받은 선물 카드 (direction=RECEIVED):
- 상대방은 선물을 보낸 팬이다.
- 받은 선물 empty
- 제목:
전달 예정인 선물이 없어요 - 본문:
베타 기간에는 팬이 선물을 보내는 기능만 제공돼요. 더 다양해진 선물 기능으로 곧 다시 만나요! - 버튼:
의견 남기기, 기존 문의/피드백 이동 패턴 사용
- 제목:
- 받은 선물 있음 상단 안내 배너
- 제목:
배송지 입력 기간 안내 - 본문:
알림을 받은 날부터 7일 이내에 배송지를 입력해 주세요. 기한 내 입력하지 않으면 선물이 반송됩니다.
- 제목:
- 배송지 입력이 필요한 선물이 있으면 리스트 상단에 파란 안내 배너 표시
- 제목:
팬이 보낸 선물이 있어요! - 본문:
선물이 늦지 않게 전달될 수 있도록 배송지를 입력해 주세요. - 보조 문구는
recipientAddressRegistered=false이고recipientAddressDeadlineAt이 있으면 남은 일수로 표시한다. - 배송지가 이미 입력되어
recipientAddressRegistered=true이면recipientAddressDeadlineAt은 null로 온다. - 배너 탭 시 배송지 입력이 필요한 첫 번째 선물 상세로 이동
- 제목:
- 카드에는 팬 프로필/닉네임,
{createdAt} 신청, 상태 메인/서브 문구, chevron 표시 - 하단
문의하기버튼은 기존 앱 정책에 맞춰 고정 또는 스크롤 내부 버튼으로 둔다.
상태 표시 매핑:
- 보낸 선물 카드
RECEIVED:운송장 등록 필요TRACKING_REGISTERED:발송 확인ARRIVED_AT_MAILBOX:사서함 도착INSPECTION_COMPLETED:선물 검수 완료DELIVERED:전달 완료UNDELIVERABLE:전달 불가CANCELED:신청 취소
- 받은 선물 카드
TRACKING_REGISTERED: main배송지 입력 필요, sub전달 예정ARRIVED_AT_MAILBOX: main선물 검수, sub선물 확인 중INSPECTION_COMPLETED: main선물 검수 완료, sub배송 중DELIVERED: main전달 완료, sub 없음UNDELIVERABLE: main전달 불가, sub 없음
- 공통 선물 상세 화면
API:
- Method:
GET - URL:
/api/v2/gifts/{applicationNo} - 리스트 item 탭, 신청 완료 후 이동, 푸시 딥링크 진입 모두 이 API로 상세를 조회한다.
Response data 핵심 필드:
{
"applicationNo": "A-1002609300001",
"direction": "SENT",
"status": "RECEIVED",
"statusName": "접수 완료",
"giftInfo": {
"recipientCreatorNickname": "달빛수집가",
"senderNickname": null,
"sizeName": "소형",
"categoryName": "잡화",
"applicationNo": "A-1002609300001",
"paidCan": 100,
"tracking": null,
"shippingRequestedAt": null
},
"senderInfo": {
"name": "김소다",
"phoneNumber": "01012345678",
"address": "(04030) 서울특별시 마포구 양화로 000, 3층"
},
"recipientAddress": null,
"mailbox": {
"name": "소다라이브 사서함",
"address": "(06174) 서울특별시 강남구 테헤란로108길 8, 유민빌딩 4층",
"phoneNumber": "02-2055-1477"
},
"trackingRequired": true,
"recipientAddressRequired": false,
"recipientAddressDeadlineAt": null,
"delivery": {
"canceledAt": null,
"undeliverableAt": null,
"undeliverableReason": null
},
"statusTimeline": []
}
진입 처리:
- 화면 진입 시 상세 API 호출
- 로딩 중에는 기존 상세 로딩/스켈레톤 패턴 사용
- 실패 시 기존 toast/dialog와 재시도 패턴 사용
direction이 현재 화면 분기와 맞지 않아도 별도 화면을 만들지 말고 같은 상세 화면 안에서direction기준으로 렌더링한다.
진행 상태 progress:
- Figma의 진행 단계가 4단계처럼 보여도 4단계로 하드코딩하지 않는다.
- API
statusTimeline의 정상 진행 5개 상태를 이 순서로 표시한다.RECEIVED:신청 접수TRACKING_REGISTERED:발송 확인ARRIVED_AT_MAILBOX:사서함 도착INSPECTION_COMPLETED:검수 완료DELIVERED:전달 완료
occurredAt이 있으면 완료 색상과MM.DD표시occurredAt=null이면 비활성 색상, 날짜 미표시UNDELIVERABLE,CANCELED는 progress step으로 추가하지 않는다.
- 보낸 선물 상세와 운송장 등록
Figma:
- 상세 운송장 등록 전
2481:19011 - 상세 운송장 등록 후
2481:19152 - 상세 전달 완료
2481:19320 - 전달 불가
2481:19456 - 취소 다이얼로그
2481:19500 - 취소 완료
2481:19521 - 운송장 등록 입력 전
2481:19066 - 운송장 등록 입력 완료
2481:19109
적용 조건:
direction=SENT
상단 타이틀:
- 일반 상세:
신청 상세 - 취소 완료 페이지:
취소 완료 - 운송장 등록:
운송장 등록
보낸 상세 hero 문구:
RECEIVED: title선물 신청 완료!, body선물이 정상적으로 접수되었어요!TRACKING_REGISTERED: chip발송 확인, title사서함으로 이동 중이에요ARRIVED_AT_MAILBOX: chip사서함 도착, title선물이 사서함에 도착했어요INSPECTION_COMPLETED: chip검수 완료, title선물 검수를 완료했어요DELIVERED: chip전달 완료, title크리에이터에게 선물을 전달했어요UNDELIVERABLE: chip전달 불가, title전달할 수 없는 품목입니다, body보내주신 선물은 SODALIVE 선물 정책에 따라 크리에이터에게 전달할 수 없는 품목으로 확인되었습니다.CANCELED: 일반 상세 대신 취소 완료 UI 표시
보낸 상세 섹션:
- 선물 정보는 항상 표시
- 크리에이터:
giftInfo.recipientCreatorNickname - 사이즈:
giftInfo.sizeName - 카테고리:
giftInfo.categoryName - 신청번호:
applicationNo또는giftInfo.applicationNo - 캔:
giftInfo.paidCan이 null이 아닐 때 표시 - 운송장:
giftInfo.tracking이 null이 아닐 때 표시 - 검수일/전달 완료일은
statusTimeline에서 찾는다.
- 크리에이터:
senderInfo가 있으면 보내는 사람 섹션 표시mailbox가 있으면 보내실 주소/받는 사서함 섹션 표시delivery.undeliverableReason이 있으면 사유 섹션 표시recipientAddress는 보낸 팬 상세에 표시하지 않는다.
보낸 상세 action:
trackingRequired=true이면 주요 CTA운송장 작성하기표시, 운송장 등록 화면으로 이동direction=SENT && status=RECEIVED이면 보조 action신청 취소표시 가능status=DELIVERED && direction=SENT이면 기존 리뷰 작성 화면/플로우가 있으면리뷰 남기기연결문의하기,선물 정책 확인은 기존 이동 경로가 있으면 연결하고, 없으면 숨기거나 기존 앱 정책에 맞춰 처리
신청 취소:
신청 취소탭 시 즉시 API 호출 금지, 기존v2 dialog확인 팝업 표시- 제목:
신청 취소 - 본문:
{크리에이터}에게 보내는 선물을 취소할까요?선물 보내기 규정에 따라 선물 취소 및 사용한 캔이 모두 환불됩니다.
- 왼쪽 action:
나가기, dialog만 닫음 - 오른쪽 destructive action:
취소하기,POST /api/v2/gifts/{applicationNo}/cancel호출 - 실패 시 dialog를 닫지 말고 기존 에러 패턴 표시
- 성공 시 취소 완료 페이지로 replace navigation
취소 완료 페이지:
- 상세 API 응답이
status=CANCELED인 경우에도 표시 - hero title:
선물 신청이 취소되었어요 - hero body:
{크리에이터}에게 보내는 선물 신청({applicationNo})이 취소되었습니다. 취소한 신청은 되돌릴 수 없으며, 다시 보내려면 새로 신청해 주세요. - 취소 상세: 크리에이터, 사이즈, 카테고리, 신청번호, 신청일, 취소일, 환불 캔
- 뒤로가기는 취소 전 상세/등록 화면으로 돌아가지 않게 한다.
운송장 등록 화면:
- 상세에서
trackingRequired=true일 때만 진입 - 진입 시 상세 API를 다시 조회
- 조회 결과
trackingRequired=false이면 기존 오류 처리 후 상세로 복귀 - 신청 건 요약 카드:
applicationNo, 크리에이터 닉네임,sizeName · categoryName · 신청일 - 보내실 주소:
mailbox사용.mailbox=null이면 등록을 막고받을 주소가 등록되어 있지 않습니다.오류 표시 - 운송장 정보: 택배사 select, 운송장 번호 input
- 등록 안내: Figma 안내 문구 유지
- 하단 action bar: 왼쪽
신청 취소, 오른쪽등록 완료
택배사 로컬 상수:
let giftCourierCompanyNames = [
"CJ대한통운",
"우체국택배",
"GS25 편의점택배",
"CU 편의점택배",
"한진택배",
"롯데택배",
"로젠택배",
"경동택배",
"대신택배",
"일양로지스",
"천일택배",
"합동택배",
"건영택배",
"농협택배"
]
- 이미 앱 공통 택배사 상수가 있으면 그것을 우선 사용
- API에는 선택한 한글 표시명을 그대로
courierCompanyName으로 보낸다.
운송장 등록 CTA 활성 조건:
- 택배사 선택됨
- 운송장 번호가 공백이 아님
- submit 중 중복 탭 방지
운송장 등록 API:
- Method:
POST - URL:
/api/v2/gifts/{applicationNo}/tracking - Request:
{
"courierCompanyName": "한진택배",
"trackingNumber": "123456789012"
}
- 성공 시 성공 toast 표시 후 상세 페이지로 돌아가거나 replace navigation으로 상세를 다시 열고, 상세 API를 재조회해
TRACKING_REGISTERED상태를 표시한다.
- 받은 선물 상세와 배송지 입력
Figma:
- 배송지 입력 전
2531:36290 - 배송지 입력 완료
2531:36399 - 전달 완료
2531:36330 - 전달 불가
2531:36422
적용 조건:
direction=RECEIVED
받은 상세 개인정보 규칙:
senderInfo,mailbox,giftInfo.applicationNo,giftInfo.paidCan,giftInfo.tracking은 표시하지 않는다.recipientAddress=null이면 받는 주소 섹션 전체를 숨긴다. 빈 섹션, skeleton,-값도 표시하지 않는다.- 전달 불가 화면에서는
recipientAddress가 응답에 있어도 받는 주소 섹션을 표시하지 않는다.
배송지 입력 전 UI:
- 적용 조건:
direction=RECEIVED && recipientAddressRequired=true - 상단 타이틀:
선물 받기 - 개인정보 이용 안내 배너
- 제목:
개인정보 이용 안내 - 본문:
크리에이터 및 팬의 주소는 공개되지 않습니다. 입력한 배송지는 선물 전달 및 필요한 사고 처리에서 사용되며, 전달 완료 후 파기됩니다.
- 제목:
- 전달 예정 선물 섹션
- 발송인:
giftInfo.senderNickname - 사이즈:
giftInfo.sizeName - 카테고리:
giftInfo.categoryName
- 발송인:
- 배송지 입력 섹션
- 이름
recipientName - 휴대폰 번호
recipientPhoneNumber - 우편번호
recipientZipCode - 주소
recipientAddress - 상세 주소
recipientAddressDetail
- 이름
- 우편번호 검색은 기존 앱 주소 검색/Kakao 우편번호 래퍼를 재사용
- 이용 약관 동의
소다라이브 크리에이터 상품 전달 이용약관 및 전달 가능 제한 품목을 확인하고 동의합니다.(필수)->recipientTermsAgreed상품 전달을 위해 수령인 성명·연락처·주소 등 필요한 개인정보를 일시적으로 수집·이용하는 것에 동의합니다.(필수)->recipientPrivacyAgreed- 각 약관 문구의
(필수)부분은 터치 가능한 링크로 처리한다. (필수)터치 시 약관 Notion 웹페이지로 이동한다.- sender 약관 2개와 recipient 약관 2개는 모두 같은 Notion 페이지로 이동하면 된다.
- Notion 페이지 URL은 실제 구현 시 입력받도록 처리하고, 이 프롬프트에서 임의 URL을 하드코딩하지 않는다.
- 하단 CTA:
선물 받기 - CTA 활성 조건: 이름, 휴대폰, 우편번호, 주소 입력됨 + 약관 2개 동의됨
배송지 입력 API:
- Method:
POST - URL:
/api/v2/gifts/{applicationNo}/recipient-address - Request:
{
"recipientName": "크리에이터이름",
"recipientPhoneNumber": "01012345678",
"recipientZipCode": "04030",
"recipientAddress": "서울특별시 마포구 양화로 000",
"recipientAddressDetail": "3층",
"recipientTermsAgreed": true,
"recipientPrivacyAgreed": true
}
- 성공 시 성공 toast 표시 후 상세 API를 다시 조회하거나 replace navigation으로 상세를 다시 열어 배송지 입력 완료 UI를 표시한다.
- 실패 시 기존 form error/toast/dialog 패턴을 따르고 입력값은 유지한다.
배송지 입력 완료 상세:
- 적용 조건:
direction=RECEIVED && recipientAddressRequired=false && status가TRACKING_REGISTERED,ARRIVED_AT_MAILBOX,INSPECTION_COMPLETED중 하나이며recipientAddress가 있음 - 상단 타이틀:
선물 상세 - hero title:
배송지 입력 완료! - hero body:
빠른 시일 내로 선물을 전달 드릴게요. 문의하기버튼은 기존 카카오 채널 문의로 연결- 선물 정보: 발송인, 사이즈, 카테고리, 배송 신청일
- 받는 주소:
recipientAddress.name,recipientAddress.phoneNumber,recipientAddress.address
전달 완료 상세:
- 적용 조건:
direction=RECEIVED && status=DELIVERED - hero title:
선물 전달 완료! - hero body:
팬이 보낸 선물이 도착했어요. 선물이 도착하지 않은 경우, 문의해 주세요. - 선물 정보: 발송인, 사이즈, 카테고리, 배송 신청일, 배송 완료일
- 받는 주소가 있으면 표시하고 보조 문구
배송 완료 3일 후 해당 정보는 사라져요표시
전달 불가 상세:
- 적용 조건:
direction=RECEIVED && status=UNDELIVERABLE - chip:
전달 불가 - hero title:
전달할 수 없는 품목입니다 - hero body:
해당 선물은 SODALIVE 선물 정책에 따라 크리에이터에게 전달할 수 없는 품목으로 확인되었습니다. 문의하기: 기존 카카오 채널 문의로 연결선물 정책 확인: 실제 외부 URL을 임의 연결하지 않는다. 기존 앱 정책상 no-op 금지이면준비 중입니다.toast만 표시- 사유 섹션
- 제목:
delivery.undeliverableReason이 있으면 그 값, 없으면전달 불가 - 안내 문구:
해당 선물은 정책에 따라 폐기되며 반송되지 않습니다.
- 제목:
- 배송지 입력 UI는 표시하지 않는다.
- 푸시/딥링크
- 선물 푸시 딥링크는
deepLinkValue=GIFT_DETAIL,deepLinkId=applicationNo를 사용한다. - 딥링크 진입 시 바로 특정 보낸/받은 화면을 결정하지 말고,
GET /api/v2/gifts/{applicationNo}를 호출한 뒤 응답의direction,trackingRequired,recipientAddressRequired,status로 상세 UI를 결정한다. - 권한 오류 또는 미존재 오류는 기존 앱 딥링크 오류 처리 패턴을 따른다.
- API 요약
GET /api/v2/gifts/form-options: 선물 신청 폼 옵션 조회POST /api/v2/gifts: 선물 신청 접수GET /api/v2/gifts?type=ALL&page=0&size=20: 선물함 리스트 조회GET /api/v2/gifts/{applicationNo}: 선물 상세 조회POST /api/v2/gifts/{applicationNo}/cancel: 보낸 선물 신청 취소POST /api/v2/gifts/{applicationNo}/tracking: 보낸 선물 운송장 등록POST /api/v2/gifts/{applicationNo}/recipient-address: 받은 선물 배송지 입력POST /api/v2/gifts/{applicationNo}/review: 전달 완료 후 팬 리뷰 작성, 기존 리뷰 플로우가 있을 때 연결
- 검증 체크리스트
- 선물 보내기 진입 시 전달받은 크리에이터 닉네임과
memberId가 각각 화면/API에 연결되는지 확인한다. - 화면 진입 시
GET /api/v2/gifts/form-options가 호출되는지 확인한다. - 필수 입력/동의가 누락되면 신청 API를 호출하지 않는지 확인한다.
requiresDamageWaiver=true카테고리에서만 파손 면책 동의가 표시되고 필수인지 확인한다.- 선물 신청 성공 후
applicationNo로 상세 페이지로 이동하는지 확인한다. - 신청 완료 후 뒤로가기로 입력 폼에 돌아와 중복 신청하지 않는지 확인한다.
- 선물함 리스트는
type=ALL로 한 번 조회하고direction으로 카드 UI를 나누는지 확인한다. - Figma의
신청 내역,선물 내역섹션 타이틀이 실제 화면에 노출되지 않는지 확인한다. - 리스트 item 탭, 푸시 딥링크, 신청 완료 이동이 모두 같은 상세 조회 플로우를 사용하는지 확인한다.
direction=SENT상세에서 팬 본인 발신자 정보와 사서함만 표시하고, 크리에이터 배송지는 표시하지 않는지 확인한다.direction=RECEIVED상세에서 팬 닉네임만 표시하고 팬의 이름/휴대폰/주소는 표시하지 않는지 확인한다.direction=RECEIVED상세에서mailbox,giftInfo.paidCan,giftInfo.tracking이 표시되지 않는지 확인한다.- 상세 progress가
statusTimeline5단계를 사용하고 Figma처럼 4단계로 하드코딩되지 않았는지 확인한다. trackingRequired=true일 때만 운송장 등록 CTA가 표시되는지 확인한다.- 운송장 등록 성공 후 상세를 재조회해
TRACKING_REGISTERED상태를 표시하는지 확인한다. - 신청 취소는 확인 dialog 이후에만 API를 호출하고, 성공 시 취소 완료 페이지로 replace 되는지 확인한다.
recipientAddressRequired=true일 때 받은 선물 배송지 입력 UI가 표시되는지 확인한다.- 배송지 입력 성공 후 상세를 재조회해 배송지 입력 완료 UI가 표시되는지 확인한다.
recipientAddress=null이면 받는 주소 섹션을 통째로 숨기는지 확인한다.status=UNDELIVERABLE이면 전달 불가 UI와 사유/폐기 안내를 표시하고 배송지 입력 UI를 숨기는지 확인한다.- 모든 날짜는 UTC ISO 문자열을 앱 표시 형식으로 변환하는지 확인한다.
- API 실패 시 기존 앱 오류 표시 방식을 사용하고 입력값/스크롤 상태를 불필요하게 초기화하지 않는지 확인한다.