2020/07/03

苹果appstore应用退款通知


配置

配置事件通知服务,可接收有关 App 内购买项目的重要事件(例如订阅状态变更或 App 内购买项目退款)的相关 App Store 通知。

  • 1、登录app应用后台 https://appstoreconnect.apple.com/
  • 2、选择需要通知的app应用。
  • 3、点击侧边栏的综合 -> App 信息
  • 4、在App Store 服务器通知网址 (URL)处填写接收通知URL(必须为https)。

/blog/img/appstore01.jpg

接收内容

常见用户苹果充值后退款方式:

  • 1、联系Apple客户支持并要求退款。
  • 2、登录并使用Apple的自助服务工具 reportaproblem.apple.com 要求退款。
  • 3、要求他们的付款方式发行人退款。

当用户退款后,苹果会通过配置url通知到我们,根据退款信息我们自行对游戏内玩家进行资源扣除,封号等操作。

以下是一条退款通知例子

[
  "notification_type" => "REFUND" #通知类型 REFUND 为消耗性内购商品退款
  "environment" => "PROD" #收据生成的环境 沙箱环境Sandbox、 生产环境PROD
  "latest_receipt" => "" #最新的Base64编码的交易收据
  "latest_receipt_info" => [ #最新交易收据内容
    "cancellation_reason" => "1"
    "is_trial_period" => "false"
    "is_in_intro_offer_period" => "false"
    "unique_identifier" => "e90e1f5a42241ded3708f250f87012881af2be28"
    "unique_vendor_identifier" => "CFA8F97E-085E-43D7-AC2B-E922DA79D80A"
    "cancellation_date" => "2020-07-01 14:49:38 Etc/GMT" #退款时间
    "cancellation_date_ms" => "1593614978000"
    "cancellation_date_pst" => "2020-07-01 07:49:38 America/Los_Angeles"
    "purchase_date" => "2020-06-02 21:57:54 Etc/GMT" #购买时间
    "purchase_date_ms" => "1591135074000"
    "purchase_date_pst" => "2020-06-02 14:57:54 America/Los_Angeles"
    "original_purchase_date" => "2020-06-02 21:57:54 Etc/GMT"
    "original_purchase_date_ms" => "1591135074000"
    "original_purchase_date_pst" => "2020-06-02 14:57:54 America/Los_Angeles"
    "item_id" => "1220328027"
    "app_item_id" => "1220322901" #Apple ID
    "version_external_identifier" => "835702051"
    "bid" => "com.yoda.p16.ztsang"
    "product_id" => "rxsgios_yueka" #内购商品
    "transaction_id" => "150000658177060" #苹果订单号
    "original_transaction_id" => "150000658177060"
    "quantity" => "1"
    "bvrs" => "19391"
  ]
  "unified_receipt" => [ #退款的订单信息在此
    "status" => 0 #状态代码,0表示有效
    "environment" => "Production" #收据生成的环境 沙箱环境Sandbox、 生产环境Production
    "latest_receipt" => "xxx"
    "latest_receipt_info" => [ #最近100笔订单信息
      0 => [
        "quantity" => "1"
        "product_id" => "rxsgios_yueka"
        "transaction_id" => "150000658177060"
        "purchase_date" => "2020-06-02 21:57:54 Etc/GMT"
        "purchase_date_ms" => "1591135074000"
        "purchase_date_pst" => "2020-06-02 14:57:54 America/Los_Angeles"
        "original_purchase_date" => "2020-06-02 21:57:54 Etc/GMT"
        "original_purchase_date_ms" => "1591135074000"
        "original_purchase_date_pst" => "2020-06-02 14:57:54 America/Los_Angeles"
        "is_trial_period" => "false"
        "original_transaction_id" => "150000658177060"
        "cancellation_date" => "2020-07-01 14:49:38 Etc/GMT" #退款时间,一定要确保此字段存在才能保证此单是退款
        "cancellation_date_ms" => "1593614978000"
        "cancellation_date_pst" => "2020-07-01 07:49:38 America/Los_Angeles"
        "cancellation_reason" => "1" #用户退款的原因。(0或1,含义未知)
      ]
      1 => [
        "quantity" => "1"
        "product_id" => "rxsgios_yueka"
        "transaction_id" => "150000592844922"
        "purchase_date" => "2020-01-15 16:06:39 Etc/GMT"
        "purchase_date_ms" => "1579104399000"
        "purchase_date_pst" => "2020-01-15 08:06:39 America/Los_Angeles"
        "original_purchase_date" => "2020-01-15 16:06:39 Etc/GMT"
        "original_purchase_date_ms" => "1579104399000"
        "original_purchase_date_pst" => "2020-01-15 08:06:39 America/Los_Angeles"
        "is_trial_period" => "false"
        "original_transaction_id" => "150000592844922"
        "cancellation_date" => "2020-01-16 09:32:57 Etc/GMT"
        "cancellation_date_ms" => "1579167177000"
        "cancellation_date_pst" => "2020-01-16 01:32:57 America/Los_Angeles"
        "cancellation_reason" => "0"
      ]
    ]
  ]
  "bid" => "com.yoda.p16.ztsang" #bundle id
  "bvrs" => "19391" #App的版本号
]

通知类型 notification_type=REFUND ,即消耗类内购商品退款, unified_receipt 存放着历史退款订单信息,我们可以循环处理每条退款内容,根据每条退款订单下的苹果订单编号 transaction_id 找到一一对应我们自身订单,记录好每一笔退款,查出详情,针对用户进行扣除资源扣除或封号。

简单一个php处理思路

$data = json_decode($appcb, true);

// 如果非消耗类退款
if ($data['notification_type'] != 'REFUND') {
    return;
}
// 如果非生产环境则不处理
if ($data['environment'] != 'PROD') {
    return;
}

// 通过获取bundle id判断属于哪款游戏
$bid = $data['bid'];

$unified = $data['unified_receipt'];

// 如果退款列表状态不合理
if ($unified['status'] !== 0) {
    return;
}
// 如果退款列表非生产环境则不处理
if ($unified['environment'] !== 'Production') {
    return;
}

// 每一笔退款订单
$latest_receipt_info = $unified['latest_receipt_info'];
foreach ($latest_receipt_info as $val) {
    // 如果不存在退款时间则认为此属于正常订单,非退款
    if (!isset($val['cancellation_date'])) {
        continue;
    }
    // 内购产品
    $product_id = $val['product_id'];
    // 苹果订单
    $transaction_id = $val['transaction_id'];
    // 通过苹果订单找到一一对应我方自身订单,进行校验、落地存储、玩家扣除资源或封号等处理。
    // ------
}

苹果官方相关说明链接

处理退款通知
启动服务器通知

苹果通知返回json数据responsebody
responsebody
responsebody.latest_receipt_info
responsebody.unified_receipt