设置快速订阅
有关快速订阅的概述,请参阅快速订阅概述。当您准备好开始操作时,请联系您的亚马逊代表,让他们在您的账户上启用“快速订阅”。然后,按照本页面上的步骤进行操作。
- 先决条件
- 步骤1: 在开发者控制台中配置快速订阅
- 步骤2: 配置安全配置文件
- 步骤3: 实现getPurchaseUpdates
- 步骤4: 集成收据验证服务 (RVS)
- 步骤5: 将履行结果发送给亚马逊
- 步骤6: 集成实时通知 (RTN)
- 步骤7: 集成一键账户信息共享功能
- 步骤8: 使用LAT测试快速订阅
- 相关主题
先决条件
与Appstore SDK版本3.0.6或更高版本集成。有关详细信息,请参阅集成Appstore SDK。
步骤1: 在开发者控制台中配置快速订阅
可供客户在应用内购买的任何订阅应该也可通过快速订阅购买,快速订阅中提供的所有订阅都应可在应用内购买。例外情况:如果应用内可供购买的订阅数量达到5个以上,则必须从中选择4个订阅以将其通过快速订阅提供。
要为应用配置快速订阅,请按照以下步骤操作。
- 登录开发者控制台。
- 在应用列表中,找到要设置为使用快速订阅的应用。
- 在应用程序内商品列中,单击链接打开“应用程序内商品”屏幕。
- 选择创建快速订阅。
- 随即出现一个叠加弹出窗口,如下图所示。
选择默认订阅下拉列表中列出了现有IAP订阅。选择要启用快速订阅的订阅。
- 在选择期限下拉列表中,选择快速订阅的期限。
- 如果要为快速订阅提供其他订阅,请选择添加其他快速订阅。您最多可以添加四个快速订阅。
- 勾选相应的复选框,选择快速订阅的目标设备。
- 选择是仅为动态应用测试 (LAT) 创建快速订阅,还是同时为LAT和上线应用创建快速订阅。
- 要仅为LAT创建快速订阅,请选择为测试创建快速订阅。
- 要为LAT和上线应用创建快速订阅,请选择为测试和上线创建快速订阅。
注意: 有关如何使用LAT测试快速订阅的详细信息,请参阅使用LAT测试快速订阅。
创建了快速订阅后,可以选择快速订阅商品对应的操作,删除或修改创建的快速订阅。
步骤2: 配置安全配置文件
要为应用配置安全配置文件,请按照以下步骤操作。
- 登录开发者控制台。
- 打开应用列表并选择应用。
- 选择应用服务,然后滚动到安全配置文件部分。
- 单击选择现有安全配置文件或新建以展开相关选项。
- 通过下拉列表选择要映射到该应用的安全配置文件,然后单击启用安全配置文件。或者,也可通过单击创建安全配置文件来创建新的安全配置文件。
步骤3: 实现getPurchaseUpdates
onResume()
方法中调用getPurchaseUpdates()
。getPurchaseUpdates()
方法可获取用户收据。快速订阅使用来自getPurchaseUpdates()
的信息来验证用户的购买状态,从而确保用户能够访问其有权访问的内容。
在onResume()
方法中调用getPurchaseUpdates()
。getPurchaseUpdates()
方法使用一个布尔参数:reset
。将reset
设置为false
,可仅返回自上次调用此方法之后生成的新收据。将reset
设置为true
可返回此用户的所有收据。
@Override
protected void onResume() {
super.onResume();
//...
PurchasingService.getUserData();
//...
PurchasingService.getPurchaseUpdates(false);
}
有关如何集成getPurchaseUpdates()
方法的更多信息,请参阅IAP API文档:
- Android—实现getPurchaseUpdates方法
- 网页应用—getPurchaseUpdates(reset)
实现要求
按照这些要求来正确实现getPurchaseUpdates()
方法。
- 必须在Android活动的
onResume()
生命周期方法中调用getPurchaseUpdates()
。 - 在
onResume()
中调用getPurchaseUpdates()
获取最新收据时,请务必使用false
标记。如果使用true
标记,它将返回收据的完整历史记录,并且您必须添加额外的筛选逻辑来处理响应。 - 在您的应用中添加“Restore Purchases”(恢复购买)选项,当客户选择该选项时,该选项会使用
true
标记调用getPurchaseUpdates()
。 - 务必持久存储通过
getPurchaseUpdates()
收到的收据,并且必须将该收据映射到应用的登录ID。使用此映射在客户打开应用时解锁其订阅的内容。
步骤4: 集成RVS
使用收据验证服务 (RVS),可以验证应用用户进行的购买。向RVS服务器发出请求后,返回的JSON响应包含一个purchaseMetadataMap
字段。如果使用快速订阅发起了购买,则purchaseMetadataMap
会显示为{"QuickSubscribe":"true"}
,如下例所示。
{
"autoRenewing": true,
"betaProduct": false,
"binCountryCode": null,
"cancelDate": 1641131573000,
"cancelReason": 2,
"deferredDate": null,
"deferredSku": null,
"freeTrialEndDate": null,
"fulfillmentDate": 1641131345000,
"fulfillmentResult": "FULFILLED",
"gracePeriodEndDate": null,
"parentProductId": null,
"productId": "IntroFreeTrial.sku",
"productType": "SUBSCRIPTION",
"promotions": null,
"purchaseDate": 1641131345000,
"purchaseMetadataMap": {
"QuickSubscribe": "true"
},
"quantity": null,
"receiptId": "k9om1rUS7gZJIg8RMfw7AlbxA3aP56ay-vdgeLU40zw=:3:11",
"renewalDate": null,
"term": "1 Month",
"termSku": null,
"testTransaction": false
}
如果没有使用快速订阅发起购买,则purchaseMetadataMap
会显示为null。下表提供了响应对象中所有字段的说明。
字段 | 数据类型 | 描述 |
---|---|---|
autoRenewing |
布尔值 | 表示客户的订阅是否会自动续订。 |
betaProduct |
布尔值 | 指示所购买的产品是否是动态应用测试产品。 |
cancelDate |
长整数 | 取消购买的日期,或订阅到期的日期。如果购买未取消,则此字段为null。时间以毫秒为单位。 |
cancelReason |
整数 | 指示取消产品的原因。可能的值为null、0、1或2,其中每个整数分别代表一项取消原因: null - 购买未取消。0 - 当前无法提供取消原因,将在之后提供。1 - 客户取消了订单。2 - 亚马逊系统取消了购买。例如,客户用于购买订阅的付款无效,并且无法在宽限期内完成购买。如果亚马逊客户支持部门应客户要求取消订单,也会返回此代码。 |
freeTrialEndDate |
长整数 | 表示订阅处于免费试用期内。提供订阅免费试用的结束日期,以epoch(毫秒)为单位。如果订阅不在免费试用期内,则此字段为null。 |
fulfillmentDate |
长整数 | 在订阅购买中,为确认履行的日期。以纪元以后的毫秒数存储。如果未确认订阅履行,则为null。消费品和权利始终为null。 |
fulfillmentResult |
字符串 | 在订阅购买中,履行的状态。有效值:
|
gracePeriodEndDate |
长整数 | 表示订阅处于宽限期内。提供订阅宽限期的结束日期,以epoch(毫秒)为单位。如果订阅不在宽限期内,则此字段为null。 |
parentProductId |
字符串 | Null。预留以供将来使用。 |
productId |
字符串 | 您在应用中为此商品定义的SKU。 |
productType |
字符串 | 所购买产品的类型。有效产品类型为CONSUMABLE 、SUBSCRIPTION 和ENTITLED 。 |
promotions |
List<Promotion> | 订阅购买的促销定价或留存优惠的详细信息。如果没有促销,则为Null。请参阅RVS中的促销。 |
purchaseDate |
长整数 | 购买日期,以纪元以后的毫秒数存储。对于订阅商品,purchaseDate 代表首次购买日期,而不是后续续订的购买日期。 |
purchaseMetadataMap |
Map <String, String> | 如果购买是通过快速订阅发起的,则值为{"QuickSubscribe":true} 。否则为null。 |
quantity |
整数 | 购买的数量。始终为null或1。 |
receiptId |
字符串 | 购买的全局唯一标识符。 |
renewalDate |
长整数 | 需要续订订阅购买的日期。日期以纪元以后的毫秒数存储。 |
term |
字符串 | 订阅IAP将保持有效的持续时间(期限从购买之日开始)。期限由数字和时间段(天、周、月、年)构成,如1周或2个月。 |
termSku |
字符串 | 对应于订阅期的唯一SKU。 |
testTransaction |
布尔值 | 表明此购买是否作为亚马逊发布和测试过程的一部分进行。 |
有关RVS的更多详细信息,请参阅适用于Appstore SDK IAP的收据验证服务。
步骤5: 将履行结果发送给亚马逊
当您发送履行结果时,请确保亚马逊可以确认用户是否可以访问其付费购买的内容。务必将履行结果传达给亚马逊。为此,请使用Appstore SDK中包含的notifyFulfillment()
方法。
客户登录后,在履行订阅后使用状态FULFILLED
调用notifyFulfillment()
。如果客户已经订阅,则使用状态UNAVAILABLE
调用notifyFulfillment()
,表明客户已登录但购买不适用。有关notifyFulfillment()
方法的更多信息,请参阅将履行结果发送给亚马逊并向用户授予商品。
如果之前已集成确认收据API,则可以继续使用它来代替notifyFulfillment()
方法。必须在应用中使用notifyFulfillment()
方法或确认收据API来将履行结果传达给亚马逊。
实现要求
请按照这些要求来正确实现notifyFulfillment()
方法。
- 每次客户打开应用并尝试访问内容时,都必须调用
notifyFulfillment()
。 - 如果成功将客户映射到收据并为该客户解锁订阅内容,则必须使用
FULFILLED
状态调用notifyFulfillment()
。 - 如果确定客户已有订阅,则必须使用
UNAVAILABLE
状态调用notifyFulfillment()
。 - 如果之前因遇到问题而使用
UNAVAILABLE
调用了notifyFulfillment()
,则在成功将客户映射到收据并为该客户解锁订阅内容后,务必要使用FULFILLED
状态调用notifyFulfillment()
。
确认收据API
notifyFulfillment()
方法,而不是确认收据API。如果已经集成了确认收据API,则可以继续使用它。步骤6: 集成RTN
借助快速订阅,客户可以通过亚马逊订阅您的应用,而不是通过您的应用订阅。这可能会导致您的应用缺少部分关于客户购买状态的信息。getPurchaseUpdates()
方法仅在应用打开时发送数据。
实时通知 (RTN) 可为所有交易提供客户购买信息,包括发生在您应用以外的交易。您的服务器收到来自亚马逊RTN服务器的购买通知后,请使用适用于Appstore SDK IAP的收据验证服务 (RVS) 验证收据。
有关如何设置RTN的详细信息,请参阅使用实时通知。
步骤7: 集成一键账户信息共享功能
按照本指南操作,可让您的应用集成一键账户信息共享功能。
更新应用清单
要向亚马逊应用商店表明您的应用支持一键账户信息共享功能,请使用以下代码更新您的应用清单。
<uses-feature android:name="amazon.lwa.quicksignup.supported"/>
实现getUserData更改
要确定客户是否明确同意与您的应用共享其亚马逊账户详细信息,您必须在应用初始化期间实现以下流程。
在应用主要活动的onCreate()
方法中:
- 创建新的
UserDataRequest
对象并将其配置成请求客户的个人资料同意状态信息。要将UserDataRequest
对象配置成请求同意状态,请将其setFetchUserProfileAccessConsentStatus()
方法设置为true。 - 调用
getUserData()
方法并将配置的UserDataRequest
对象传递给该方法。
以下示例说明如何构建UserDataRequest
对象并将其传递给getUserData()
。
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//...
// 传递要注册的PurchasingListener的引用
PurchasingService.registerListener(this.getApplicationContext(), purchasingListener);
// 传递要注册的UserProfileAccessListener的引用
PurchasingService.registerUserProfileAccessListener(this.getApplicationContext(), userProfileAccessListener);
// 在isLoggedIn() 中实现逻辑以识别客户的登录状态
if (!isLoggedIn()) {
PurchasingService.getUserData(UserDataRequest.newBuilder().setFetchUserProfileAccessConsentStatus(true).build());
}
//...
}
实现onUserDataResponse()
回调方法以获取UserDataResponse
对象,该对象包含客户同意数据。以下代码展示了如何处理从UserDataResponse
对象收到的同意数据。
@Override
public void onUserDataResponse(final UserDataResponse response) {
UserDataResponse.RequestStatus status = response.getRequestStatus();
switch (status) {
case SUCCESSFUL:
if (UserProfileAccessConsentStatus.CONSENTED.equals(response.getUserData().getUserProfileAccessConsentStatus())) {
// 启动自定义加载器屏幕或微调器。
PurchasingService.requestUserProfileAccess();
}
break;
case FAILED:
case NOT_SUPPORTED:
// 优雅地失败。
break;
}
}
如果客户已表示同意,则UserData
对象的UserProfileAccessConsentStatus
状态为CONSENTED
。如果客户未表示同意,或者同意令牌已过期,则UserProfileAccessConsentStatus
的状态为UNAVAILABLE
。
如果客户表示同意,则调用requestUserProfileAccess()
方法,并使用响应对象中的授权代码更新您的服务器。然后,使用Appstore SDK提供的REST API,获取访问令牌和客户配置文件。使用共享的用户信息,在您的系统中创建账户。
以下代码展示了如何从UserProfileAccessResponse
对象提取用户配置文件访问授权代码。
@Override
public void onUserProfileAccessResponse(final UserProfileAccessResponse response) {
UserProfileAccessResponse.RequestStatus status = response.getRequestStatus();
switch (status) {
case SUCCESSFUL:
// 此处应使用userProfileAccessAuthCode更新您的服务,
// 进一步与Appstore SDK REST API交互以获得访问令牌和客户配置文件。
final String userProfileAccessAuthCode = response.getUserProfileAccessAuthCode();
break;
case FAILED:
case NOT_SUPPORTED:
// 优雅地失败。
break;
}
}
如果客户不同意,请显示您自己的登录屏幕。然后,客户可以使用键盘输入凭证或登录您的应用。
获取访问令牌API
Appstore SDK提供了获取访问令牌REST API,用于获取访问令牌。本节介绍相应的请求、响应和错误。
访问令牌请求
应用收到包含有效授权代码的授权响应后,可使用该授权代码获取访问令牌。有了访问令牌,客户端就可以读取客户配置文件。
获取访问令牌API必须使用POST请求而不是GET请求,如下例所示。
POST https://appstore-sdk.amazon.com/version/1.0/auth/o2/token?
grant_type=authorization_code
&code=SplxlOBezQQYbYS6WxSbIA
&client_id=foodev
&client_secret=foosecret
下表介绍访问令牌请求参数。
请求参数 | 描述 |
---|---|
grant_type | 必需。请求的访问权限授予类型。必须为authorization_code 。 |
code | 必需。requestUserProfileAccess() 方法返回的授权代码。 |
client_id | 必需。客户端标识符。 |
client_secret | 必需。注册过程中分配给客户端的密钥值。由于网页无法可靠地存储客户端密钥,请勿在基于浏览器的应用中使用客户端密钥。 |
访问令牌响应
要访问客户数据,必须向Appstore SDK获取用户配置文件API提供访问令牌。访问令牌是长度在350个字符或以上的字母数字代码,最大大小为2048字节。访问令牌以字符Atza|
开头。
响应参数使用application/json
媒体类型进行编码。有关更多信息,请参阅RFC4627。以下是来自访问令牌请求的示例响应。
{
"access_token":"Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX..."
}
下表介绍访问令牌响应参数。
响应参数 | 描述 |
---|---|
access_token | 用户账户的访问令牌。最大不超过2048字节。 |
token_type | 返回的令牌类型。值为bearer 。 |
expires_in | 访问令牌的有效秒数。 |
refresh_token | 刷新令牌,可用于请求新的访问令牌。最大不超过2048字节。 |
访问令牌是不记名令牌,其他客户端可以使用。有关更多信息,请参阅OAuth 2.0授权框架: 不记名令牌的使用(仅提供英文版)。
访问令牌错误
对于某些错误,授权服务可能会返回HTTP 401 (Unauthorized)
(HTTP 401 [未授权])状态代码。这包括以下情况:客户端在授权标头中传递了client_id
和client_secret
值,但无法对客户端进行身份验证。
下表介绍失败响应中的错误参数。
错误参数 | 描述 |
---|---|
error | 包含错误代码值的ASCII错误代码。 |
error_description | 人类可读的ASCII字符串,包含了错误相关信息,对客户端开发者非常有用。 |
request_id | 与您的访问令牌请求关联的ID。 |
返回的error值中可能包含以下错误代码。
获取用户配置文件API
Appstore SDK提供了获取用户配置文件REST API,用于获取用户配置文件数据。本节介绍相应的请求、响应和错误。
用户配置文件请求
要访问授权的用户配置文件数据,请使用获取用户配置文件API将访问令牌提交至亚马逊应用商店。获取用户配置文件API使用HTTPS GET请求,并将从获取访问令牌API收到的访问令牌作为其唯一参数。
下例展示了获取用户配置文件数据的GET请求。
GET https://appstore-sdk.amazon.com/version/1.0/user/profile?
access_token=Atza|IQEBLjAsAhRmHjNgHpi0U-Dme37rR6CuUpSR...
请求参数 | 描述 |
---|---|
access_token | 必需。从获取访问令牌API收到的访问令牌。 |
用户配置文件响应
如果访问令牌有效,则会在HTTP响应中收到JSON形式的客户配置文件数据,如下例所示。
{
"user_id": "amznl.account.K2LI23KL2LK2",
"email":"mhashimoto-04@plaxo.com",
"name" :"Mork Hashimoto",
"postal_code": "98052"
}
如果在履行您的配置文件请求时出现问题,则会收到HTTP错误,并且可能会收到包含更多信息的JSON有效负载,如下例所示。
{
"error": "machine-readable error code",
"error_description": "human-readable error description",
"request_id": "bef0c2f8-e292-4l96-8c95-8833fbd559df"
}
下表介绍在用户配置文件请求失败时可能返回的错误代码。
状态 | 错误代码 | 描述 |
---|---|---|
200 | Success | 请求成功。 |
400 | invalid_request | 请求缺少必需的参数或存在格式错误。 |
400 | invalid_token | 提供的访问令牌已过期、已撤销、格式错误或由于其他原因无效。 |
401 | insufficient_scope | 提供的访问令牌没有所需范围的访问权限。 |
500 | ServerError | 服务器运行错误。 |
流程图
下图展示了采用一键账户信息共享功能的快速订阅代码流程。
账户设置的最佳实践
请遵循以下客户账户设置的最佳实践。
- 如果
UserProfileAccessConsentStatus
在getUserData()
响应中的值为CONSENTED
,请执行以下操作:- 从Appstore SDK获取用户配置文件API中获取用户信息。使用此信息来创建采用临时密码的登录帐户。无需向客户请求重置密码或提供其他详细信息,即可让客户登录应用。
- 之后,通过电子邮件要求客户重置密码。
- 如果
UserProfileAccessConsentStatus
的值为UNAVAILABLE
,请为客户使用默认的应用注册体验。
步骤8: 使用LAT测试快速订阅
要使用动态应用测试 (LAT) 测试快速订阅,请先使用在开发者控制台中配置快速订阅中的步骤,在开发者控制台中为LAT配置快速订阅。您可以仅为LAT配置快速订阅,也可以为上线应用和LAT应用配置快速订阅,如下图所示。
如果您选择仅为LAT配置快速订阅,则稍后可以通过选择操作>升级为上线版本,将配置升级到上线应用,如下图所示。
如果您对LAT应用进行的快速订阅配置与对上线应用进行的配置不同,则LAT应用的快速订阅详细信息中会显示测试标签,如下图所示。
您可以通过亚马逊零售网站或Fire设备测试快速订阅流程。当您开始动态应用测试时,可以向测试者发送邀请。测试者会收到一封电子邮件,其中会附上提供LAT版本应用的亚马逊网站链接。
在网站上测试快速订阅
在LAT邀请电子邮件中,选择您所在市场的亚马逊网站。在应用详情页面上,选择订阅选项,该选项显示为订阅期限的付费选项,例如每月20.00美元。然后选择要交付至哪个设备,接着单击Get App(获取应用)。
在设备上测试快速订阅
要开始在设备上测试快速订阅,您可以使用LAT邀请电子邮件或设备通知。
通过LAT邀请进行测试:
- 使用邀请电子邮件中的链接转到亚马逊网站上的应用详情页面。
- 选择App Only(仅限应用)选项。
- 在Deliver to:(交付至)下拉菜单中,选择Cloud Only(仅限云)。
- 单击Get App(获取应用)。
- 在与亚马逊账户关联的Fire TV设备上,单击Your Apps & Channels(您的应用和频道)的图标(该图标在导航栏上显示为三个正方形和一个加号)。
- 找到您应用的LAT版本,该应用的图标上有一个TEST(测试)横幅。您可能需要单击App Library(应用库)才能查看该应用。
- 选择应用图标以打开设备上的应用详情页面。
- 选择Subscription Options(订阅选项)并下载应用。
通过通知进行测试:
发送LAT邀请后,与测试者电子邮件相关联的测试设备会收到通知。如果您在通知出现时打开通知,则会进入LAT应用详情页面。此通知会显示5-10秒。如果您在通知首次出现时错过了通知,可以单击设置图标(齿轮图标)并选择Notifications(通知)来查看它。然后您可以阅读通知并转到应用详情页面。选择Subscription Options(订阅选项)并下载应用。
重要须知
- 在以下情况下,不支持通过LAT测试快速订阅:
- 当您选择要交付到哪个具体设备时,请使用网站上的App Only选项。
- 使用设备上的App Only选项。
-
要通过LAT就快速订阅以外的目的测试应用,您可以使用App Only选项并选择要将应用交付到哪个具体设备。
-
在测试快速订阅时关闭加速订阅。
-
要重置测试账号的快速订阅,可前往开发者控制台为LAT重置订阅。有关详细信息,请参阅为LAT中的所有测试者重置应用内商品或管理单个测试者。
- 如果您想将30天的取消时间范围缩短为1天的测试时间范围,请联系您的亚马逊代表。
相关主题
Last updated: 2024年12月18日