建议所有提供消耗型/非消耗型/自动续期订阅/非续期订阅商品的App均配置该通知接收地址,以便接收关键事件通知,为用户提供更好、更及时的服务。另外,通知接收地址必须基于HTTPS并且配置有商业域名机构颁发的证书。
如果接入了IAP Kit订单/订阅功能,建议在AppGallery Connect网站配置通知接收地址,用于接收IAP服务器发送的关键事件通知。IAP关键事件通知版本只支持v3。
建议所有提供消耗型/非消耗型/自动续期订阅/非续期订阅商品的App均配置该通知接收地址,以便接收关键事件通知,为用户提供更好、更及时的服务。另外,通知接收地址必须基于HTTPS并且配置有商业域名机构颁发的证书。
用户购买消耗型/非消耗型/自动续期订阅/非续期订阅商品后,IAP服务器调用此接口向开发者服务器发送关键事件通知。
如果在AppGallery Connect申请支付服务时提前配置通知接收地址,并且通知版本设置为v3,用户购买消耗型/非消耗型/自动续期订阅/非续期订阅商品后,IAP服务器会在某些关键事件发生时调用此接口通知已配置的服务器。
消耗型/非消耗型/非续期订阅商品主要涉及的场景如下:
支付成功。
退款成功。
自动续期订阅商品主要涉及的场景如下:
用户第一次订阅成功。
已过期的订阅自动续期成功。
用户主动恢复一个已过期的自动续期订阅商品。
用户调整为相同等级的自动续期订阅商品,如果订阅商品的周期相同,则新订阅立即生效。
用户调整为相同等级的自动续期订阅商品,如果订阅商品的周期不相同,则新订阅在下个续期日生效。
用户调整为更高等级的自动续期订阅商品,则新订阅立即生效,原订阅的剩余金额将折算成新订阅的天数,延长新订阅的有效期。
用户调整为更低等级的自动续期订阅商品,则新订阅在下个续期日生效
用户主动或者App取消一个自动续期订阅商品,已经收费的服务仍然有效,但是后续续期会停止。
一个自动续期订阅商品成功续期。
一个到期的自动续期订阅商品进入账号保留期。
订阅的续期时间已延期。
若开发者服务器返回结果为非成功响应(请求返回的HTTP状态码不为200),IAP服务器将对本次关键事件的通知进行周期性重发。建议在收到通知后立即返回成功响应,避免通知消息堆积。
为保证可靠性,系统具备补偿机制,所以可能出现重发的通知比预期的多。
沙盒测试场景下通知失败不会进行重发。
开发者服务器收到IAP服务器的关键事件通知(下文简称事件通知)时,建议根据通知内容中的购买Token,请求IAP服务器校验购买Token获取当前购买Token关联订单/订阅的最新状态,并根据订单/订阅最新状态决定是否需要提供商品服务。
事件通知仅作为订单/订阅状态发生变化的一个事件通知,由于网络延迟等导致服务器收到通知事件有延迟,通知中携带的信息可能与IAP服务器的最新的状态不一致,建议不要根据事件通知来决定是否提供商品服务。
收到DID_NEW_TRANSACTION通知类型后,建议根据如下通知处理流程进行业务逻辑处理,提供商品服务。
关键事件通知处理流程建议如下:

不允许开发者服务器设置IP允许清单用于限制华为侧的出口IP地址。IP允许清单本身并不能提高安全性且会给业务发展带来约束,在消息层面已有更安全的JWS签名机制条件下,没有存在价值。不遵守该约定而导致的后果将由开发者自行承担。
必须在开发前在AppGallery Connect中配置开发者服务器的回调地址,地址必须支持HTTPS协议且具有合法商用证书,出于安全考虑,cipher需要支持ECDHE-RSA-AES128-GCM-SHA256、ECDHE-ECDSA-AES128-GCM-SHA256、ECDHE-RSA-AES256-GCM-SHA384或ECDHE-ECDSA-AES256-GCM-SHA384中至少一种,否则无法正常接收通知消息。
华为IAP关键事件通知仅通过IPv4链路发送,请确保回调地址支持IPv4访问。若回调地址仅支持IPv6,将无法正常接收通知消息。
承载协议: HTTPS POST
接口方向: IAP服务器 -> 开发者服务器
接口URL: URL由开发者在申请支付服务时配置
数据格式:
请求消息:Content-Type: application/json; charset=UTF-8
响应消息:Content-Type: application/json; charset=UTF-8
| 参数 | 是否必选 | 参数类型 | 描述 |
|---|---|---|---|
| jwsNotification | 是 | String | 通知内容信息,对通知内容NotificationPayload签名后的字符串。具体请参见表NotificationPayload。 需要参见对返回结果验签使用JWS签名方式对NotificationPayload消息体进行验签。 |
| 参数 | 是否必选 | 参数类型 | 描述 |
|---|---|---|---|
| notificationType | 是 | String | 通知主类型,具体请参见表NotificationType说明。 |
| notificationSubtype | 否 | String | 通知子类型,具体请参见表NotificationSubtype说明。后续子类型会增加,开发者需要设计相应的处理机制。 |
| notificationRequestId | 是 | String | 通知唯一请求ID。 |
| notificationMetaData | 是 | Object | 通知元数据,具体请参见表NotificationMetaData说明。 |
| notificationVersion | 是 | String | 通知版本:v3。 |
| signedTime | 是 | Long | 通知签名时间,UTC时间戳,以ms为单位。 |
服务端关键事件通知可能会在后续版本中新增参数和取值。开发者在处理通知时应保留兼容性,避免因收到非预期的类型而导致程序异常或中断。
| 取值 | 取值说明 |
|---|---|
| DID_NEW_TRANSACTION | 订单已购买/订阅已购买/订阅续订成功。 |
| DID_CHANGE_RENEWAL_STATUS | 订阅状态发生改变。 |
| REVOKE | 消耗型/非消耗型/非续期订阅商品:订单退款。 自动续期订阅商品:撤销订阅。 |
| RENEWAL_TIME_MODIFIED | 订阅过期时间调整。 |
| EXPIRE | 订阅已过期。 |
| TEST | 测试服务端通知,仅开发者调用测试服务端通知接口才会发送此类型通知。 此场景下无notificationSubtype。 |
| 取值 | 取值说明 |
|---|---|
| INITIAL_BUY | 消耗型/非消耗型/非续期订阅商品购买成功。 自动续期订阅商品的第一次购买成功。 使用主类型:DID_NEW_TRANSACTION |
| DID_RENEW | 续期成功。 使用主类型:DID_NEW_TRANSACTION |
| RESTORE | 用户主动恢复了一个订阅型商品,续期恢复正常。 使用主类型:DID_NEW_TRANSACTION |
| AUTO_RENEW_ENABLED | 自动续期功能开启。 使用主类型:DID_CHANGE_RENEWAL_STATUS |
| AUTO_RENEW_DISABLED | 自动续期功能关闭。 使用主类型:DID_CHANGE_RENEWAL_STATUS |
| DOWNGRADE | 用户调整自动续期订阅商品降级或跨级且在下个续订生效。 使用主类型:DID_CHANGE_RENEWAL_STATUS或DID_NEW_TRANSACTION |
| UPGRADE | 用户调整自动续期订阅商品升级或跨级且立即生效。 使用主类型:DID_NEW_TRANSACTION |
| REFUND_TRANSACTION | 消耗型/非消耗型/非续期订阅商品:订单退款成功。 自动续期订阅商品:订单退款成功且撤销对应订阅成功,订阅权益会立即取消。 使用主类型:REVOKE |
| BILLING_RETRY | 一个到期的自动续期订阅商品进入账号保留期。 使用主类型:EXPIRE |
| PRICE_INCREASE | 用户同意了涨价。 使用主类型:DID_CHANGE_RENEWAL_STATUS |
| BILLING_RECOVERY | 订阅重试扣费成功。 使用主类型:DID_NEW_TRANSACTION |
| VOLUNTARY | 主动退订后订阅过期。 使用主类型:EXPIRE |
| PRODUCT_NOT_FOR_SALE | 商品不存在。 使用主类型:EXPIRE |
| APPLICATION_DELETE_SUBSCRIPTION_HOSTING | 撤销订阅成功,订阅权益会立即取消。 使用主类型:REVOKE |
| RENEWAL_EXTENDED | 延迟订阅续订日期成功,订阅的下一个续订日期将推迟。 使用主类型:RENEWAL_TIME_MODIFIED |
| 参数 | 是否必选 | 参数类型 | 描述 |
|---|---|---|---|
| environment | 是 | String | 环境类型。 - NORMAL:正式环境 - SANDBOX:沙盒环境 |
| applicationId | 是 | String | 应用Id。 |
| packageName | 是 | String | 应用包名。 |
| type | 是 | Integer | 商品类型。 0:消耗型商品 1:非消耗型商品 2:自动续期订阅商品 3:非续期订阅商品 |
| currentProductId | 否 | String | 最近一个有效订阅的商品ID。仅自动续期订阅商品场景下存在值。 |
| subGroupId | 否 | String | 订阅组ID。仅自动续期订阅商品场景下存在值。 |
| subGroupGenerationId | 否 | String | 订阅组的代ID。 - 用户切换订阅商品时,此ID不会改变。 - 订阅失效且超出保留期后,用户重新购买商品时,此ID会改变。 |
| subscriptionId | 否 | String | 商品的订阅ID。以下场景,此ID会发生改变: - 用户切换订阅商品时。 - 订阅失效且超出保留期后,用户重新购买商品时。 |
| purchaseToken | 是 | String | 商品的购买Token,发起购买和查询订阅信息均会返回。最大长度256。 |
| purchaseOrderId | 否 | String | 具体一笔订单中对应的购买订单号。当NotificationType为DID_CHANGE_RENEWAL_STATUS且NotificationSubtype为DOWNGRADE时不返回purchaseOrderId。 最大长度256。 |
POST /notify/address
Content-Type: application/json;charset=UTF-8
Accept: application/json
{
"jwsNotification": "***"
} NotificationPayload样例(消耗型/非消耗型)
{
"notificationType": "DID_NEW_TRANSACTION",
"notificationSubtype": "INITIAL_BUY",
"notificationRequestId": "7f67e39aa72d1a55f36293047f9769c0aa47a467ffb110eaeeeb888def9f9713",
"notificationMetaData": {
"environment": "NORMAL",
"applicationId": "***",
"packageName": "***",
"type": 0,
"purchaseToken": "***.*.***",
"purchaseOrderId": "***.***"
},
"notificationVersion": "v3",
"signedTime": 1702607152698
} NotificationPayload样例(非续期订阅商品)
{
"notificationType": "DID_NEW_TRANSACTION",
"notificationSubtype": "INITIAL_BUY",
"notificationRequestId": "7f67e39aa72d1a55f36293047f9769c0aa47a467ffb110eaeeeb888def9f9713",
"notificationMetaData": {
"environment": "NORMAL",
"applicationId": "***",
"packageName": "***",
"type": 3,
"purchaseToken": "***.*.***",
"purchaseOrderId": "***.***"
},
"notificationVersion": "v3",
"signedTime": 1702607152698
} NotificationPayload样例(自动续期订阅商品)
{
"notificationType": "DID_NEW_TRANSACTION",
"notificationSubtype": "INITIAL_BUY",
"notificationRequestId": "6d5882d55c8e5136f2348b8e13b4aaad6d0938898b7e5efdc13f7c7130286f8c",
"notificationMetaData": {
"environment": "NORMAL",
"applicationId": "***",
"packageName": "***",
"type": 2,
"currentProductId": "1701072721154732",
"subGroupId": "1701072721154732",
"subGroupGenerationId": "f7967e2439769fbb3c155a50d2cdd6a8cc8f7750cac7bf78b6f5d65c97c34deb",
"subscriptionId": "1701072722814.ADE66B39.4732",
"purchaseToken": "***.*.***",
"purchaseOrderId": "***.*.***"
},
"notificationVersion": "v3",
"signedTime": 1701072726860
} 通过HTTP状态码来标识IAP服务器通知开发者服务器是否发送成功:
如果通知发送成功,则发送HTTP 200,不需要返回响应体。
如果通知发送失败,则通过发送HTTP 40X或者HTTP 50X,告知IAP服务器进行重试,IAP服务器会在一段时间内重试多次。
HTTP/1.2 200 OK