diff --git a/src/api/billingApi.js b/src/api/billingApi.js index 73b619c..720c159 100644 --- a/src/api/billingApi.js +++ b/src/api/billingApi.js @@ -22,4 +22,8 @@ export const billingApi = { resume() { return http.post('/billing/resume') }, + // 구매 복원 (기기 변경·재설치) + restore() { + return http.post('/billing/restore') + }, } diff --git a/src/views/settings/AccountInfoView.vue b/src/views/settings/AccountInfoView.vue index b2638b8..0f0a775 100644 --- a/src/views/settings/AccountInfoView.vue +++ b/src/views/settings/AccountInfoView.vue @@ -111,6 +111,25 @@ async function resumeSub() { } } +async function restoreSub() { + if (subBusy.value) return + subBusy.value = 'restore'; subMsg.value = ''; subErr.value = '' + try { + sub.value = await billingApi.restore() + await auth.refreshProfile() + subMsg.value = sub.value?.premium ? '구매가 복원되었습니다.' : '복원할 결제 내역이 없습니다.' + } catch (e) { + subErr.value = e.response?.data?.message || '복원에 실패했습니다.' + } finally { + subBusy.value = '' + } +} + +// 포인트 기프트콘 교환 — 업데이트 예정 +function exchangeGiftcon() { + dialog.alert('포인트 기프트콘 교환은 업데이트 예정입니다. 조금만 기다려 주세요!') +} + // 플랜 구독/변경 — Android 만 결제, PC 는 업그레이드(앱 안내) 화면으로 async function choosePlan(product) { if (!isNative) { @@ -265,6 +284,10 @@ async function withdraw() { 내역 › + @@ -331,6 +354,12 @@ async function withdraw() {

📱 구독 결제·변경은 모바일 앱에서 진행됩니다.

+
+ +
+

{{ subMsg }}

{{ subErr }}

@@ -431,6 +460,19 @@ async function withdraw() { color: hsla(160, 100%, 37%, 1); font-weight: 700; } +.soon { + font-size: 0.74rem; + font-weight: 600; + padding: 0.1rem 0.45rem; + border-radius: 999px; + background: var(--color-background-mute); + color: var(--color-text); + opacity: 0.7; +} +.restore-row { + padding: 0.4rem 1.1rem 0.2rem; + text-align: right; +} .row-point { width: 100%; border: 0;