Object.keys(record).sort().map(key => `${key}=${record[key]}`).join('&')).join('&') // const sign = hmacsha256(signStr, hashSort) // 定义一个空数组,用来存放每个记录的键值对字符串 $record_strings = array(); // 遍历 records 数组,对每个记录进行排序和拼接 foreach ($records as $record) { // 对记录的键进行升序排序 ksort($record); // 把记录的键值对用等号连接,然后用 & 连接成一个字符串 $record_string = http_build_query($record); // 把字符串加入到 record_strings 数组中 $record_strings[] = $record_string; } // 把 record_strings 数组用 & 连接成一个字符串 $records_string = implode("&", $record_strings); $hash_data = 'channel=' . $channel . '&' . $records_string; $signature = hash_hmac('sha256', $hash_data, BUY_SERVER_PKEY); if ($signature != $sign) { $this->_rspErr(1, "signature error, signature: {$signature}, sign: {$sign}"); return; } $conn = myself()->_getMysql(''); // 有三种情况: // 1. 从商城购买钻石,有订单号 // 2. 站外充值钻石,没有订单号 // 3. appstore 退款,没有订单号 for ($i = 0; $i < count($records); $i++) { $record = $records[$i]; $product_id = $record['productId']; $order_id = $record['gameOrderId']; $out_order_id = $record['orderId']; $status = $record['status']; switch ($status) { case 9: { $status = 1; if (empty($order_id)) { if (empty($product_id)) { $this->_rspErr(2, "product_id is empty"); return; } // $goods = mt\ShopGoods::getByProductId($product_id); return; } $order = SqlHelper::selectOne($conn, 't_web2_order', array('address', 'id', 'item_id', 'goods_num', 'status'), array('order_id' => $order_id, 'status' => 0)); error_log('process order ' . json_encode($order)); if (!$order) { $this->_rspErr(3, "order not found, order_id: {$order_id}"); return; } SqlHelper::update($conn, 't_web2_order', array('order_id' => $order_id), array('status' => $status, 'channel' => $channel, 'out_order_id' => $out_order_id)); $id = $order['id']; $goods = ShopGoods::get($id); // 这里命名混乱了, 购买个数,一捆个数命名冲突 $goods_num = $order['goods_num']; $bundle_size = $goods['goods_num']; $item_num = $goods_num * $bundle_size; $item_id = $goods['goods_id']; $address = $order['address']; if (empty($address)) { $this->_rspErr(4, "address is empty"); return; } $account_id = $this->getAccountId($address); if (empty($account_id)) { $this->_rspErr(5, "account_id is empty"); return; } if ($item_id == V_ITEM_DIAMOND) { $event = [ 'name' => LogService::RECHARGE_DIAMOND, 'val' => $item_num ]; LogService::productDiamondCallback(['account_id' => $account_id], $event); } $this->_addGoods($address, array( 'goods_id' => $item_id, 'goods_num' => $item_num, 'id' => $id, )); } break; case 96: $status = 3; if (empty($order_id)) { if (empty($product_id)) { $this->_rspErr(2, "product_id is empty"); return; } // $goods = mt\ShopGoods::getByProductId($product_id); return; } // 退款 $order = SqlHelper::selectOne($conn, 't_web2_order', array('address', 'id', 'item_id', 'goods_num', 'status'), array('order_id' => $order_id, 'status' => 1)); if (!$order) { $this->_rspErr(3, "order not found, order_id: {$order_id}"); return; } SqlHelper::update($conn, 't_web2_order', array('order_id' => $order_id), array('status' => $status)); $id = $order['id']; $goods = ShopGoods::get($id); // 这里命名混乱了, 购买个数,一捆个数命名冲突 $goods_num = $order['goods_num']; $bundle_size = $goods['goods_num']; $item_num = $goods_num * $bundle_size; $item_id = $goods['goods_id']; $address = $order['address']; if (empty($address)) { $this->_rspErr(4, "address is empty"); return; } $account_id = $this->getAccountId($address); if (empty($account_id)) { $this->_rspErr(5, "account_id is empty"); return; } if ($item_id == V_ITEM_DIAMOND) { $event = [ 'name' => LogService::RECHARGE_DIAMOND, 'val' => -$item_num ]; LogService::productDiamondCallback(['account_id' => $account_id], $event); } $this->_decGoods($address, array( 'goods_id' => $item_id, 'goods_num' => $item_num, 'id' => $id, )); break; default: $status = 0; $this->_rspErr(1, "status is not 9 or 96"); return; break; } } $this->_rspOk(); } private function getAccountId($address) { $row = SqlHelper::ormSelectOne( myself()->_getMysql($address), 't_user', array( 'address' => $address ) ); if (!$row) { return null; } return $row['account_id']; } private function _addGoods($address, $goods) { $itemService = new ShopAddItemService(); $item_id = $goods['goods_id']; $goods_num = $goods['goods_num']; $id = null; if ($goods['id']) { $id = $goods['id']; } error_log('_addGoods ' . $address . ' item_id ' . $item_id . ' goods_num ' . $goods_num . ' id ' . $id); $itemService->addItem($address, $item_id, $goods_num); if ($id) { ShopBuyRecord::addWithAddress($address, $id, $goods_num); } } private function _decGoods($address, $goods) { $itemService = new ShopAddItemService(); $item_id = $goods['goods_id']; $goods_num = $goods['goods_num']; error_log('_decGoods ' . $address . ' item_id ' . $item_id . ' goods_num ' . $goods_num); $itemService->decItem($address, $item_id, $goods_num); } private function _rspOk() { echo json_encode(array( 'errcode' => 0, 'errmsg' => "callback success", )); } private function _rspErr($errcode, $errmsg) { if (SERVER_ENV != _ONLINE) { error_log(json_encode(array( 'errcode' => $errcode, 'errmsg' => $errmsg, ))); } echo json_encode(array( 'errcode' => $errcode, 'errmsg' => $errmsg, )); } }