S Subster

Быстрый старт

Вы подключите библиотеку или свой сервер и получите от нас первый ответ о доступе покупателя — от получаса до дня, смотря берёте ли вы нашу библиотеку.

Отдайте задачу ИИ-помощнику

Скопируйте промпт, оставьте в нём свою платформу и подставьте ID проекта.

I am integrating Subster into a mobile app. Subster takes subscription payments
on a web page, outside the app store, and opens the paid access inside the app.

Platform: iOS / Android / server-side code in <language>
API address: https://api.subster.ai
Project ID: <PROJECT_ID>

What the app has to do:
1. get the buyer id (guid) from the link that returns the user to the app
   after payment;
2. ask Subster for that buyer's entitlement;
3. open the paid flow if at least one of the returned grants has
   status "active".

Take every endpoint and field name from the Subster documentation: its MCP
server is https://api.subster.ai/mcp, or use the pages I attach. If a field or
an endpoint is not there, ask me — do not invent names or addresses.

Как подключить MCP-сервер к помощнику — «MCP-сервер».

Перед началом

Значения лежат в кабинете: Настройки проекта → Подключение приложения → Для разработчика.

Кабинет открылся не на том языке — переключите его в «Личных настройках» → «Персонализация»: «Аккаунт и безопасность».

Сниппет под вашу платформу

Копируйте код с этой страницы: пример на вкладке «Для разработчика» в кабинете пока устарел и не собирается.

iOS

В Xcode: File → Add Package Dependencies, адрес https://github.com/web2web-dev/web2app-ios-sdk.git, версия 0.8.1, продукт Web2AppSDK. Нужна iOS 14 или новее.

import Web2AppSDK

// once at launch — baseUrl is a URL, not a String
Web2App.configure(projectId: "<PROJECT_ID>", baseUrl: URL(string: "https://api.subster.ai")!)

// identify the buyer: pass the one-time code from the return link,
// or nil on first launch without a link — then the library tries the device fingerprint
Web2App.identify(deepLinkValue: code) { result in
    // .success(guid); .failure(.needsEmailFallback) — nothing matched:
    // ask for an email and call Web2App.requestEmailRecovery(email) { _ in }
}

// check access
Web2App.entitlement { grant in
    let isPaid = grant?.isActive ?? false
}

Android

Нужен Android 7.0 или новее. Библиотека берётся из JitPack:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

// build.gradle.kts of the app module
dependencies {
    implementation("com.github.web2web-dev:web2app-android-sdk:0.7.2")
}
import app.web2app.sdk.Web2AppSdk

// once at launch — needs a context, baseUrl is a String
Web2AppSdk.configure(context, "<PROJECT_ID>", "https://api.subster.ai")

// first launch after install from Google Play: the library reads Install Referrer itself
Web2AppSdk.identify(
    onResult = { result -> result.onSuccess { guid -> /* buyer identified */ } },
    onNeedEmail = { /* nothing matched: ask for an email, then Web2AppSdk.requestEmailRecovery(email) { } */ },
)

// check access
Web2AppSdk.entitlement { grant -> val isPaid = grant?.isActive == true }

Без кода из ссылки библиотека узнаёт покупателя сама: на iOS — по отпечатку устройства, на Android — по данным, которые Google Play передаёт приложению при установке (Install Referrer). Как это устроено — «Как мы узнаём покупателя».

Если приложение открыли ссылкой возврата, код из неё отдаётся другим методом — «Возврат в приложение», шаг 3.

Библиотека отвечает по самой новой записи о доступе, остальные не смотрит. Если у покупателя бывает больше одной покупки — скажем, подписка и разовая докупка, — решайте по всему списку записей (grants): готовый код в «Рецептах», раздел «Проверить доступ из приложения без библиотеки».

Свой сервер

Библиотека не нужна: приложение меняет код из ссылки возврата на идентификатор покупателя, а ваш сервер спрашивает право с ключом.

# 1. in the app: exchange the one-time code from the return link for a buyer id
curl "https://api.subster.ai/public/handoff/resolve?code=<CODE>"
# { "success": true, "data": { "guid": "abc123def456", "projectId": "…" } }

# 2. on your server: check that buyer's access
curl "https://api.subster.ai/s2s/v1/entitlement?guid=abc123def456" \
  -H "Authorization: Bearer sk_live_…"
# { "guid": "abc123def456", "testMode": false, "grants": [{ "level": "premium", "status": "active", … }] }

Меняйте код с устройства, а не с сервера: обмен принимает десять запросов в минуту с одного IP-адреса, и сервер упрётся в этот потолок, как только покупатели пойдут потоком.

Первый ответ о доступе

  1. Откройте в браузере https://api.subster.ai/public/entitlement?guid=abc123def456 — подойдёт любой идентификатор от 8 до 64 знаков.
  2. Пришло { "guid": "abc123def456", "testMode": false, "grants": [] } — адрес верный, покупок у такого покупателя нет.
  3. Действующую запись до настоящей оплаты покажут режим проверки или тестовая карта — «Диагностика», раздел «Проверить, не дожидаясь настоящей оплаты».

Весь путь целиком

  1. Оплата. Покупатель платит на экране с ценами, вне магазина приложений. Из рекламы он попадает туда через вашу воронку, от вас ничего не нужно; из приложения — по ссылке, которую ваш сервер получает запросом POST /s2s/v1/users: «Возврат в приложение», раздел «Продажа кнопкой внутри приложения».
  2. Возврат. Экран после оплаты и письмо ведут покупателя в приложение ссылкой возврата с одноразовым кодом, а если приложения нет — сначала в магазин: «Возврат в приложение».
  3. Опознание. Приложение меняет код на идентификатор покупателя, а после установки узнаёт его другими путями: «Как мы узнаём покупателя».
  4. Проверка доступа. Доступ открыт, если среди записей есть хотя бы одна со статусом active: «Проверить право доступа».
  5. Дальше по подписке. О продлениях, отменах и возвратах ваш сервер узнаёт нашими событиями, приложение — повторным запросом права: «Вебхуки».

Дальше