Singular
Singular 是一个移动测量合作伙伴(MMP)平台,用于收集和展示营销活动数据。
Adapty 会将您选择的订阅事件发送至 Singular。在 Singular 看板中,您可以查看每个广告活动产生的收入,并评估广告效果。
设置集成
将 Adapty 连接到 Singular
要设置与 Singular 的集成,请在 Adapty 看板中前往 Integrations > Singular,打开开关并填写相关字段。
以下凭据可供填写:
- Singular SDK Key:必填。您 Singular 应用的生产环境 SDK 密钥。
- Singular SDK Key (Sandbox):选填。您 Singular 沙盒应用的 SDK 密钥。若未设置,沙盒事件将不会发送到 Singular。
这两个密钥均可在 Singular 看板的 Developer tools -> SDK Keys -> SDK Key (not SDK Secret) 下找到:
配置事件和标签
在凭据下方,有三组事件可以从 Adapty 发送到 Singular。如需查看完整的 Adapty 事件列表,请参阅事件。
我们建议使用 Adapty 提供的默认事件名称,但你也可以根据需要修改事件名称。
Adapty 通过服务器到服务器的方式将订阅事件发送到 Singular,让你可以在 Singular 看板中查看所有订阅事件,并将其与你的获客广告系列关联起来。
在集成配置完成之前已创建的用户画像,无法将其事件传送至 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,无需修改任何应用代码。
- 激活 Adapty,然后启动 Singular SDK,并传入 SDID 回调:iOS 使用
sdidReceivedHandler,Android 使用SDIDAccessorHandler,React Native 和 Flutter 使用sdidReceivedCallback,Unity 使用SingularSdidAccessorHandler。 - 等待 Singular 调用回调。SDID 是异步传递到你的应用的,在 Singular SDK 启动之后才会到达。Singular 会在每次启动时调用该回调,包括设备上已存储 SDID 的情况。
- 在回调内部,调用
setIntegrationIdentifier(),使用singular_sdid作为键,将 SDID 传递给 Adapty。目前没有任何 Adapty SDK 为该键提供预定义常量,因此请直接以字符串字面量的形式填写该键名。 - 仅在
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:
| 参数 | 类型 | 描述 |
|---|---|---|
n | String | 事件名称(从 Adapty 事件映射而来)。 |
a | String | 您的 Singular SDK Key。 |
p | String | 平台(“iOS” 或 “Android”)。 |
i | String | 应用商店 App ID(Bundle ID)。 |
ip | String | 用户 IP 地址。 |
sdid | String | 仅 v2。Singular Device ID,来自 singular_sdid 集成标识符。 |
idfa | String | iOS,仅 v1。广告主标识符(大写)。 |
idfv | String | iOS,仅 v1。供应商标识符(大写)。 |
aifa | String | Android,仅 v1。Google 广告 ID(小写)。 |
andi | String | Android,仅 v1。Android ID(小写)。 |
asid | String | Android,仅 v1。App Set ID(小写)。 |
ve | String | 操作系统版本。 |
att_authorization_status | Integer | 仅 iOS。ATT 状态(例如,3 表示已授权)。 |
custom_user_id | String | 用户的 Customer User ID。 |
utime | Long | 事件的 UNIX 时间戳(秒)。 |
partner | String | 始终为 adapty,标识该事件由 Adapty 发送。 |
use_ip | Boolean | 当 Adapty 没有用户 IP 地址时为 true。 |
is_revenue_event | Boolean | 若事件包含收入则为 true,仅随收入事件发送。 |
amt | Float | 收入金额。 |
cur | String | 货币代码(例如,“USD”)。 |
purchase_product_id | String | 商店中的产品 ID。 |
purchase_transaction_id | String | 原始交易 ID。 |
e | String | 包含事件详情的 JSON 字符串(见下文)。 |
e 参数(自定义事件数据)是一个 JSON 编码的字符串,包含:
| 参数 | 类型 | 描述 |
|---|---|---|
is_revenue_event | Boolean | true 表示该事件包含收入。 |
amt | Float | 收入金额。 |
cur | String | 货币代码。 |
purchase_product_id | String | 商店中的产品 ID。 |
purchase_transaction_id | String | 原始交易 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 会为每个已启用的集成记录结果,不支持的事件将显示为失败。