라이브러리
유료 기능 잠그기
Paywall.gate로 앱 전체를 팔거나, Paywall.start와 기능별 확인 하나로 일부 기능을 파세요. 이 페이지에는 라이브러리의 모든 공개 호출과 상수, 체험의 작동 방식이 있습니다.
앱 전체 또는 일부 기능
Paywall.gate(views) | Paywall.start(views) | |
|---|---|---|
| 용도 | 앱 전체를 결제하는 앱 | 일부 기능을 판매하는 앱 |
| 실행 시, 잠김 | 앱 대신 구매 화면 | 평소대로 앱 |
| 체험 중 | 평소대로 앱 | 평소대로 앱 |
| 체험이 끝날 때 | 실행할 때마다 "체험 종료" 제목의 구매 화면 | "체험 종료" 제목의 구매 화면 한 번 |
| 구매 화면의 BACK | 앱 나가기 | 앱으로 이동 |
| 결제 후 | BACK 또는 START이 앱의 뷰를 엽니다 | BACK 또는 START이 앱으로 이동 |
| 각 유료 기능 | 추가할 것 없음 | 먼저 Paywall.unlocked() 확인 |
둘 다 getInitialView()에서 반환하는 것과 같은 배열을 받습니다. 뷰, 또는 뷰와 그 델리게이트입니다.
기능 잠그기
start를 쓰면 각 유료 기능이 시작되는 곳(버튼, 메뉴 항목, 페이지)에서 확인하세요.
source/MainDelegate.mc
function onHistory() as Void {
if (Paywall.unlocked()) {
showHistory();
} else {
Paywall.open();
}
}- 잠금 하나로 전부 열립니다. 한 번 구매하면 앱의 모든 유료 기능이 열립니다. 가격은 앱마다 하나입니다.
- 글랜스에서는
active(),unlocked(),trialLeft()만 호출하세요. 구매 화면은 앱 전용입니다. - 체험 중이 아니라 구매자에게만 보여야 하는 감사 표시는
Paywall.active()를 확인하세요.
참조
표에 따로 적힌 것이 아니면 여기 있는 모든 것은 module Paywall(Pay.mc 및 사용하는 PayScope.mc)에 있습니다.
직접 하는 호출
| 호출 | 반환값 | 하는 일 | 사용 가능 위치 |
|---|---|---|---|
Paywall.gate(views) | 반환할 뷰 | 앱 전체를 결제하는 앱의 getInitialView()에서. 체험을 시작하고, 때가 되면 서버에 묻고, 잠겨 있는 동안 앱 대신 구매 화면을 반환합니다. 결제가 끝나면 BACK 또는 START가 앱의 뷰를 엽니다. | 앱 |
Paywall.start(views) | 반환할 뷰 | 일부 기능을 판매하는 앱의 getInitialView()에서. 체험을 시작하고, 때가 되면 서버에 묻고, 앱의 뷰를 반환합니다. 체험이 끝나면 구매 화면을 한 번 보여 줍니다. | 앱 |
Paywall.unlocked() | Boolean | 결제했거나 체험 중(체험 시작 전에는 전체 기간). 모든 유료 기능에 쓰는 확인. | 앱, 글랜스 |
Paywall.active() | Boolean | 결제했고 최근 30일 안에 서버가 확인함. 체험 중에는 false. 5분 넘게 미래 시각인 "결제됨" 기록(시계 시간을 되돌린 경우)은 인정되지 않습니다. | 앱, 글랜스 |
Paywall.trialLeft() | Number | 남은 체험 일수(올림). TRIAL_DAYS를 넘지 않습니다. 체험 시작 전에는 TRIAL_DAYS 전체, 끝났거나 체험이 없으면 0. | 앱, 글랜스 |
Paywall.open() | PaywallView | 구매 화면을 띄우거나, 이미 떠 있으면 그 화면을 반환합니다. 유료 기능의 else와 설정의 "Premium" 항목에 씁니다. | 앱 |
Paywall.keys() | Array | "데이터 삭제"에서 남겨야 하는 저장소 키: "pp", "ts", "te". | 앱 |
Paywall.startTrial() | Void | 이전 호출. 처음 실행할 때 기간 체험을 시작하며, TRIAL_DAYS가 없으면 아무것도 하지 않습니다. gate와 start가 호출합니다. | 앱 |
Paywall.launch() | Void | 이전 호출. 때가 되면 서버에 묻고, 시계 시간이 뒤로 갔으면 즉시 묻습니다. gate와 start가 호출합니다. | 앱 |
Paywall.showOver() | Void | 이전 호출로, 첫 화면의 onShow()에서 호출합니다. 그 후로는 시계 밖에서 한 구매가 잠금 해제 화면을 저절로 열고, 체험이 있으면 체험이 끝날 때 구매 화면을 한 번 엽니다. gate와 start가 이 일을 대신 합니다. | 앱 |
라이브러리가 직접 호출
라이브러리가 직접 호출합니다. 내 코드에서 호출하지 마세요.
| 함수 | 하는 일 |
|---|---|
check() | 서버에 요청을 하나씩 보내며, 동시에 두 개를 보내지 않습니다. 1분 동안 응답이 없는 요청은 더 이상 세지 않습니다. |
onAnswer(code, data) | 서버의 응답을 처리합니다. 버전과 다음 확인 시각이 있는 완전한 응답만 저장합니다. 실패하면 "오프라인" 또는 "나중에 다시 시도"와 다음 시도까지의 대기 시간을 설정합니다. |
take(d) | 응답, 체험 종료 시각, "결제됨"을 저장합니다. 구매가 반영되면 잠금 해제 화면을 엽니다. |
first(views) | gate와 start의 공통 부분. |
close() | 구매 화면을 나갑니다. 결제했으면(또는 start의 체험 종료 화면 뒤에는) 앱의 뷰로, 잠긴 gate 앱에서는 앱 밖으로, 그 외에는 open()를 호출한 곳으로 돌아갑니다. |
cheer() | 시계의 성공 알림음과 진동(켜져 있는 경우). |
상수
| 상수 | 값 | 종류 |
|---|---|---|
K_ANS | "pa" | 저장소 키: 서버의 마지막 응답. |
K_PAID | "pp" | 저장소 키: 서버가 마지막으로 "결제됨"이라고 한 시각(초). 없으면 미결제. |
K_TRIAL | "ts" | 저장소 키: 체험 종료 시각. 처음 실행할 때 설정되고, 이후 서버가 설정합니다. |
K_OVER | "te" | 저장소 키: "체험 종료" 화면이 표시되었는지. |
STALE | 2592000 | 30일을 초로 나타낸 값: 서버의 새 응답 없이 "결제됨"이 유효한 기간. |
DAY | 86400 | 초 단위의 하루. |
모듈 변수
구매 화면 자체의 상태입니다. 필요하면 읽되, 절대 설정하지 마세요.
| 변수 | 담는 값 |
|---|---|
listener | 열려 있는 구매 화면 또는 null. |
status | 문제 안내 줄("오프라인" 또는 "나중에 다시 시도") 또는 null. |
busy, sentAt | 요청을 보냈는지와 보낸 시각. |
hold, held | 구매 화면이 떠 있는 동안 서버가 요청을 붙잡아 둘 수 있는 시간(처음엔 15초, 휴대폰이 끊으면 절반). |
changedAt, limit | 화면이 마지막으로 바뀐 시각과, 변화 없이 열려 있을 수 있는 시간(초). |
fails, nextAt | 연속으로 실패한 요청 수와 다음 요청 가능 시각. |
shown | 앱의 첫 화면이 떠 있음: 구매가 잠금 해제 화면을 저절로 열 수 있습니다. |
quick | 구매 화면이 열림: 첫 요청은 바로 응답이 옵니다. |
app, whole | 구매 화면이 대신하는 동안의 앱 뷰와 gate 사용 여부. |
클래스
| 클래스 | 종류 |
|---|---|
PaywallView | 구매 화면. 서버가 보낸 화면을 그리고 잠금 해제 장면을 재생합니다. |
PaywallDelegate | 구매 화면의 버튼: START와 BACK. |
PayReply | 웹 요청의 콜백 객체. |
PayBg | 워치 페이스와 데이터 필드 전용: 서버에 묻는 백그라운드 서비스. |
PaywallConfig
| 상수 | 종류 |
|---|---|
URL | 필수. 대시보드에서 받은 앱 주소. |
TRIAL_DAYS | 앱: 선택 사항이며 체험이 없으면 생략합니다. 워치 페이스와 데이터 필드: 필수이며 체험이 없으면 0. |
워치 페이스와 데이터 필드
워치 페이스와 데이터 필드는 lib/watch/face를 쓰며, 그 module Paywall에는 자체 호출이 있습니다. active(), unlocked(), trialLeft()는 위와 같이 작동합니다.
| 호출 | 하는 일 |
|---|---|
Paywall.startTrial() | 시작할 때마다 getInitialView()에서: 처음에는 체험을 시작하고, 완료된 로그인 페이지가 백그라운드를 깨울 수 있게 합니다. |
Paywall.schedule(false) | 시작할 때마다 getInitialView()에서: 다음 백그라운드 확인을 예약합니다. |
Paywall.take(d) | onBackgroundData(d)에서: 백그라운드의 응답을 저장하고 다음 확인을 예약합니다. |
Paywall.soon() | onSettingsChanged()에서: Garmin이 허용하는 즉시 확인하고, 잠겨 있으면 로그인 알림을 다시 보냅니다. |
Paywall.drawQr(dc, x, y, side) | 흰 사각형 위에 너비 side로 QR 코드를 그리며, 중심은 x, y입니다. 첫 응답 전에는 그리지 않습니다. |
Paywall.book(n) | 라이브러리가 호출: 백그라운드 확인을 예약하며, 마지막 확인 후 5분이 지나기 전에는 하지 않습니다. |
K_SIGN | "pg": 로그인 알림용 저장소 키(1 전송 대기, 2 전송됨). |
전체 설정은 워치 페이스와 데이터 필드에 있습니다.
체험
PaywallConfig에서 대시보드의 무료 체험과 같게TRIAL_DAYS를 설정하세요. 체험이 없으면 생략하세요. 그러면 "체험 종료"가 표시되지 않습니다.- 체험은 처음 실행할 때 시작됩니다. 끝날 때까지
Paywall.unlocked()는 true입니다. - 다시 설치해도 체험은 다시 시작되지 않습니다. 서버는 그 시계를 처음 본 때부터 체험 기간을 세며, 첫 응답에서 서버의 계산이 시계의 계산을 대신합니다.
- 시계 시간을 되돌려도 기간은 늘지 않습니다. 서버는 날짜가 아닌 남은 시간을 보내며, 시계는
TRIAL_DAYS보다 많은 날을 세지 않습니다. - 구매 화면 제목은 "7일 남음", "마지막 날", "체험 종료" 순으로 표시됩니다.
앱이 세는 체험 기간
일수 대신 사용 횟수로 체험을 하려면 TRIAL_DAYS를 빼고, 저장소에 자체 카운터를 두고("데이터 삭제" 후에도 유지), active()를 확인하세요:
source/MainDelegate.mc
// 20 free sessions, then Premium
if (Paywall.active() || sessionsUsed < 20) {
startSession();
} else {
Paywall.open();
}라이브러리가 저장하는 것
- 앱:
"pa"(응답),"pp"("결제됨"을 마지막으로 확인한 때),"ts"(체험 종료 시점),"te"("체험 종료" 표시 여부). - 워치 페이스와 데이터 필드:
"pa","pp","ts","pg", 그리고 설정 링크용unlock속성. - 내 키에는 다른 이름을 쓰세요.