<?php

// <editor-fold defaultstate="collapsed" desc="辅助类型,可删">

/**
 * 订单通知结构
 */
class hw_orderNotification {

    public $version;
    public $notificationType;
    public $purchaseToken;
    public $productId;

}

/**
 * hw通知结构
 */
class Hw_notify {

    /**
     * @var string V2
     */
    public $version;

    /**
     * @var long 通知时间 UnixTimeMilliseconds
     */
    public $notifyTime;

    /**
     * @var 通知类型 通知类型，取值如下：
     *      ORDER：订单
     *      SUBSCRIPTION：订阅
     */
    public $eventType;

    /**
     * @var 应用的AppId
     */
    public $applicationId;

    /**
     * @var hw_orderNotification 订单通知数据
     */
    public $orderNotification;

    /**
     * @var object 订阅通知数据
     */
    public $subNotification;

}

/**
 * 包含购买数据的订单详情 参见: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
 */
class Hw_VerifyDetails {

    public $applicationId;
    public $autoRenewing;
    public $orderId;
    public $kind;
    public $packageName;

    /**
     * @var string 关键, 这个是在华为后台配置的
     */
    public $productId;
    public $productName;
    public $purchaseTime;
    public $purchaseTimeMillis;

    /**
     * @var int 重要, 订单交易状态。
     *       -1：初始化
     *       0：已购买
     *       1：已取消
     *       2：已撤销或已退款
     *       3：待处理
     */
    public $purchaseState;

    /**
     * @var string 重要: 透传参数
     */
    public $developerPayload;

    /**
     * @var string 重要: 货币类型
     */
    public $currency;

    /**
     * @var int 重要 结算金额
     */
    public $price;
    public $purchaseToken;

    /**
     * @var string (华为)交易单号, 用户支付成功后生成.
     */
    public $payOrderId;

}

class Hw_VerifyResp {

    public $responseCode;
    public $responseMessage;

    /**
     * @var Hw_VerifyDetails 包含购买数据的订单详情
     */
    public $purchaseTokenData;
    public $dataSignature;
    public $signatureAlgorithm;

}

// </editor-fold>

/**
 * 再次恢复后台通知模式
 * @version
 *          1.0.1 海外版适配 at 2022.10.19
 *          1.0.0 接收来自客户端的发货通知(支付) (不依赖后台通知,改为验签模式)
 *                Created at 2020-9-21. by --gwang
 * @author gwang (wanggangzero@qq.com)
 * @copyright 2020.9.21, SJZ LoyalSoft Corporation & gwang. All rights reserved.
 *
 */
include_once __DIR__ . '/../../../main.php';                                                                                                                                   # 导入game utils
#
//include_once __DIR__ . '/../deliverProc.php';                                                    # 导入发货逻辑
//require_once __DIR__ . '/../Mo/OrderHuaweiModel.php';                                                                                              # 导入订单识别

require_once __DIR__ . '/order_service.php';                                                                                                                                 # 华为辅助代码

include_once __DIR__ . '/../Mo/payResp.php';                                                                                                                              # 导入通用返回值结构
include_once __DIR__ . '/../Mo/payRequest.php';                                                                                                                         # 导入通用返回值结构
require_once __DIR__ . '/../Mo/OrderNotice.php';

//require_once 'config.huawei.php';                                                                                                                                               # 配置文件
//require_once 'HuaweiSignUtils.php';                                             # 与客户端通讯验签
//require_once 'config_for_hw_oversea.php';                                       # 配置文件

use loyalsoft\CLog;
use loyalsoft\HttpUtil;
use loyalsoft\pay\OrderNotice;

header("Content-Type: application/json; charset=utf-8");

$tag = "[notify.华为] ";                                                                                                                                                                    # 日志标签
$errMsg = "success";
$result = 200;

try {

    CLog::pay("$tag收到客户端请求: " . HttpUtil::getQueryString());                                                                                 # 打日志

    $json = HttpUtil::getQueryString();                                                                                                                                          # 提取参数
//    false and $params = new Hw_notify();                                                                                                                                     # 智能感知提示
    $params = json_decode($json);                                                                                                                                                # 转为对象

    if ($params->eventType == "ORDER") {                                                                                                                                  # 是: 订单通知
        $purchaseToken = $params->orderNotification->purchaseToken;
        $productId = $params->orderNotification->productId;
        CLog::pay($tag . json_encode($params));                                                                                                             # 打日志
        $orderService = new OrderService();
        CLog::pay($tag . json_encode($orderService));                                                                                                    # 打日志
//        false and $respData = new Hw_VerifyResp();                                                      # 智能感知提示
        $respData = $orderService->verifyToken($purchaseToken, $productId);                                                                        # 去华为服务端校验purchaseToken. (内含http通讯)
        CLog::pay($tag . json_encode($respData));                                                                                                          # 打日志
# Ps. 返回值结构: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/api-order-verify-purchase-token-0000001050746113
        $responseCode = (int) ($respData->responseCode);

        if ($responseCode == 0) {
# Ps. 订单详情: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
            $purchaseTokenData = json_decode($respData->purchaseTokenData);                                                                     # 解析订单详情
            # 模拟创建订单流程
            $payReq = PayRequest::From_HW((array) $purchaseTokenData);
            if ($payReq->InserDataBase()) {                                                              # end of 模拟创建订单流程
                $order = OrderNotice::Parse_hwOrder((array) $purchaseTokenData);                                                                          # 转换为内部订单格式
                CLog::pay("$tag [order]" . json_encode($order));                                                                                                             # 打日志
                if ($order != null) {
                    if ($order->Check()) {                                                                                                                                                   # 订单校验, 1代表支付成功
                        if ($order->status == 1) {                                                                                                                                          # 订单状态是成功
                            $order->UpdateOrderStatus();                                                                                                                             # 更新订单状态,->已付款
                            $errMsg = " [发货] 订单: " . $order->cpOrderId . ", 金额: " . $order->amount;            #
                        } else if ($order->status == 2) {                                                                                         # status为2(failed)的情况
                            $order->UpdateOrderStatus();                                                                                      # 直接更新订单状态,->支付失败
                            $errMsg = "[不发货] 订单: " . $order->cpOrderId;                                                         # 这个也返回200, 不必重复通知了
                        } else {
                            $errMsg = "[处理结果]: FAILURE (未知的支付状态)";                                                        # 日志
                            $result = 502;                                                                                                                   # 这里酌情吧 500还是200
                        }
                    } else {
                        $result = 503;                                                                                                                       # 订单校验问题
                    }
                } else {
                    $errMsg = "订单归一化失败!";
                    $result = 504;
                }
            } else {
                $errMsg = "内部订单生成失败!";
                $result = 500;
            }
        } else {                                                                                                                                                      # 验签失败
            $result = 501;
            $errMsg = "去华为验签失败" . $respData->responseMessage;
        }
    } else {                                                                                                                                                                                         # 其他类型的通知, 不做处理 --gwang
        $errMsg = "invalid notify info!";
        $reult = 400;
    }
} catch (Exception $e) {                                                                                                                                                                 # 捕获异常
    $result = 500;
    $errMsg = $e->getMessage();
}
CLog::pay($tag . $errMsg);                                                                                                                                # 日志
http_response_code($result);                                                                                                                            # 设定响应码
echo($errMsg);                                                                                                                                                  # 输出body
