Singular

Singular 是一个移动测量合作伙伴(MMP)平台,用于收集和展示营销活动数据。

Adapty 会将您选择的订阅事件发送至 Singular。在 Singular 看板中,您可以查看每个广告活动产生的收入,并评估广告效果。

设置集成

将 Adapty 连接到 Singular

要设置与 Singular 的集成,请在 Adapty 看板中前往 Integrations > Singular,打开开关并填写相关字段。

singular-creds.webp

以下凭据可供填写:

  • Singular SDK Key:必填。您 Singular 应用的生产环境 SDK 密钥。
  • Singular SDK Key (Sandbox):选填。您 Singular 沙盒应用的 SDK 密钥。若未设置,沙盒事件将不会发送到 Singular。

这两个密钥均可在 Singular 看板的 Developer tools -> SDK Keys -> SDK Key (not SDK Secret) 下找到:

4bc50d1-singular_sdk_key.webp

配置事件和标签

在凭据下方,有三组事件可以从 Adapty 发送到 Singular。如需查看完整的 Adapty 事件列表,请参阅事件。

e67de0c-singular_events.webp

我们建议使用 Adapty 提供的默认事件名称,但你也可以根据需要修改事件名称。

Adapty 通过服务器到服务器的方式将订阅事件发送到 Singular,让你可以在 Singular 看板中查看所有订阅事件,并将其与你的获客广告系列关联起来。

Warning

在集成配置完成之前已创建的用户画像,无法将其事件传送至 Singular。

将您的应用连接到 Singular

Singular 为 2026 年 7 月 15 日及之后创建的账户默认启用 Singular Device ID(SDID)。这类账户仅通过 v2 Event API 接收事件,而 Adapty 只有在用户画像包含 SDID 时才会向 v2 发送事件。若要向此类账户传递事件,请在应用中将 SDID 传递给 Adapty。

如果您的 Singular 账户创建于 2026 年 7 月 15 日之前,且未启用 SDID,请跳过此步骤。Adapty 会将您的事件发送至 v1 Event API,无需修改任何应用代码。

  1. 激活 Adapty,然后启动 Singular SDK,并传入 SDID 回调:iOS 使用 sdidReceivedHandler,Android 使用 SDIDAccessorHandler,React Native 和 Flutter 使用 sdidReceivedCallback,Unity 使用 SingularSdidAccessorHandler。
  2. 等待 Singular 调用回调。SDID 是异步传递到你的应用的,在 Singular SDK 启动之后才会到达。Singular 会在每次启动时调用该回调,包括设备上已存储 SDID 的情况。
  3. 在回调内部,调用 setIntegrationIdentifier(),使用 singular_sdid 作为键,将 SDID 传递给 Adapty。目前没有任何 Adapty SDK 为该键提供预定义常量,因此请直接以字符串字面量的形式填写该键名。
  4. 仅在 setIntegrationIdentifier() 完成后再调用 Adapty.identify()。Adapty 在激活时会创建一个匿名用户画像,identify() 解析完成后才会切换到已识别的用户画像。如果在切换期间设置 SDID,该值可能会丢失。

事件结构

Adapty 根据用户画像是否包含 SDID 来选择对应的 Singular Event API 版本:

  • 包含 SDID:Adapty 向 https://s2s.singular.net/api/v2/evt 发送 POST 请求,请求体采用 form-urlencoded 编码。sdid 参数将替代设备标识符 idfa、idfv、aifa、andi 和 asid。布尔值以 true 或 false 形式发送。
  • 不含 SDID:Adapty 向 https://s2s.singular.net/api/v1/evt 发送 GET 请求,并通过查询参数传递数据。

两个版本的其他参数完全相同。v1 事件的结构如下:

{
  "n": "subscription_renewed",
  "a": "singular_sdk_key_123",
  "p": "iOS",
  "i": "com.example.app",
  "ip": "192.168.100.1",
  "idfa": "00000000-0000-0000-0000-000000000000",
  "idfv": "00000000-0000-0000-0000-000000000000",
  "ve": "17.0.1",
  "att_authorization_status": 3,
  "custom_user_id": "user_12345",
  "utime": 1709294400,
  "partner": "adapty",
  "use_ip": false,
  "is_revenue_event": true,
  "amt": 9.99,
  "cur": "USD",
  "purchase_product_id": "yearly.premium.6999",
  "purchase_transaction_id": "GPA.3383...",
  "e": "{\"is_revenue_event\":true,\"amt\":9.99,\"cur\":\"USD\",\"purchase_product_id\":\"yearly.premium.6999\",\"purchase_transaction_id\":\"GPA.3383...\"}"
}

Where:

参数类型描述
nString事件名称(从 Adapty 事件映射而来)。
aString您的 Singular SDK Key。
pString平台(“iOS” 或 “Android”)。
iString应用商店 App ID(Bundle ID)。
ipString用户 IP 地址。
sdidString仅 v2。Singular Device ID,来自 singular_sdid 集成标识符。
idfaStringiOS,仅 v1。广告主标识符(大写)。
idfvStringiOS,仅 v1。供应商标识符(大写)。
aifaStringAndroid,仅 v1。Google 广告 ID(小写)。
andiStringAndroid,仅 v1。Android ID(小写)。
asidStringAndroid,仅 v1。App Set ID(小写)。
veString操作系统版本。
att_authorization_statusInteger仅 iOS。ATT 状态(例如,3 表示已授权)。
custom_user_idString用户的 Customer User ID。
utimeLong事件的 UNIX 时间戳(秒)。
partnerString始终为 adapty,标识该事件由 Adapty 发送。
use_ipBoolean当 Adapty 没有用户 IP 地址时为 true。
is_revenue_eventBoolean若事件包含收入则为 true,仅随收入事件发送。
amtFloat收入金额。
curString货币代码(例如,“USD”)。
purchase_product_idString商店中的产品 ID。
purchase_transaction_idString原始交易 ID。
eString包含事件详情的 JSON 字符串(见下文)。

e 参数(自定义事件数据)是一个 JSON 编码的字符串,包含:

参数类型描述
is_revenue_eventBooleantrue 表示该事件包含收入。
amtFloat收入金额。
curString货币代码。
purchase_product_idString商店中的产品 ID。
purchase_transaction_idString原始交易 ID。

故障排查

事件失败,提示 invalid api version: v1

您的 Singular 账户创建于 2026 年 7 月 15 日或之后,仅接受通过 v2 Event API 发送的事件。由于用户画像中没有 SDID,Adapty 将事件发送到了 v1。要解决此问题,请按照将您的应用连接到 Singular 中的说明,从您的应用向 Adapty 传递 SDID。在没有调用 setIntegrationIdentifier() 的应用版本上的用户,在更新应用之前,其事件将持续失败。

access_level_updated 在事件动态中显示为失败

access_level_updated 是一个仅限 Webhook 的事件。Adapty 不会将其发送到此集成。但 Adapty 会为每个已启用的集成记录结果,不支持的事件将显示为失败。