_rspData( array( 'goods_list' => $goodsList, ) ); } public function buyGoods() { $goodsId = getReqVal('goods_id', 0); $goodsNum = getReqVal('goods_num', 0); if ($goodsNum < 1) { myself()->_rspErr(1, "goods_num parameter error, goods_num: {$goodsNum}"); return; } $goodsMeta = mt\ShopGoods::getByGoodsUuid($goodsId); if (!$goodsMeta) { myself()->_rspErr(1, 'goods not found'); return; } if ($goodsMeta['is_close']) { myself()->_rspErr(1, 'no right to purchase'); return; } if ($goodsNum < 1) { myself()->_rspErr(1, 'goods_num paramater error'); return; } if ($goodsNum > $goodsMeta['max_amount']) { myself()->_rspErr(1, "goods_num parameter error, max_amount: {$goodsMeta['max_amount']}"); return; } $itemMeta = mt\Item::get($goodsMeta['item_id']); if (!$itemMeta) { myself()->_rspErr(1, 'goods not found, goods_id: ' . $goodsMeta['goods_id']); return; } $errCode = 0; $errMsg = ''; if ($itemMeta['type'] == mt\Item::HERO_SKIN_TYPE) { if (!ShopService::canBuy($itemMeta, $errCode, $errMsg)) { myself()->_rspErr($errCode, $errMsg); return; } } if (!ShopService::buyLimitCheck($goodsMeta, $errCode, $errMsg)) { myself()->_rspErr($errCode, $errMsg); return; } $propertyChgService = new services\PropertyChgService(); $awardService = new services\AwardService(); $tokenType = $goodsMeta['token_type']; $price = $goodsMeta['price']; if (!in_array( $tokenType, array( mt\Shop::TOKEN_TYPE_GOLD, mt\Shop::TOKEN_TYPE_DIAMOND ) )) { myself()->_rspErr(1, "token_type is unsupport, {$tokenType}"); return; } if ($price < 1) { myself()->_rspErr(1, "config error"); return; } $costItemId = myself()->getCostItemIdByTokenType($tokenType); $costItems = array( array( 'item_id' => $costItemId, 'item_num' => $goodsNum * $price ) ); $lackItem = null; if (!myself()->_hasEnoughItems($costItems, $lackItem)) { myself()->_rspErr(2, myself()->_getLackItemErrMsg($lackItem)); return; } ShopBuyRecord::add($goodsMeta['goods_id'], $goodsNum); myself()->_decItems($costItems); for ($i = 0; $i < $goodsNum; $i++) { $this->internalAddItem($awardService, $propertyChgService, $itemMeta, $goodsMeta['item_num'] ); } switch ($tokenType) { case mt\Shop::TOKEN_TYPE_DIAMOND: { myself()->_incV(TN_TOTAL_DIAMOND_CONSUME, 0, $goodsNum * $price); } break; } $propertyChgService->addUserChg(); $this->_rspData( array( 'award' => $awardService->toDto(), 'property_chg' => $propertyChgService->toDto(), ) ); } public function outappPurchase() { $goodsId = getReqVal('goods_id', 0); $goodsNum = getReqVal('goods_num', 1); $platform = getReqVal('platform', ''); $network = getReqVal('network', ''); $crypto = getReqVal('crypto', ''); $fiat = getReqVal('fiat', ''); $fiatAmount = getReqVal('fiatAmount', ''); $payWayCode = getReqVal('payWayCode', ''); $country = getReqVal('country', ''); $address = myself()->_getAddress(); if (empty($address)) { $this->_rspErr(1, 'address is empty'); return; } if (!in_array($platform, array( 1, 2 ))) { $this->_rspErr(1, 'paramater error platform'); return; } if ($goodsNum != 1) { $this->_rspErr(1, 'goods_num is invalid'); return; } $goodsMeta = mt\ShopGoods::get($goodsId); if (!$goodsMeta) { $this->_rspErr(1, "goods_id is invalid."); return; } if ($goodsMeta['shop_id'] != mt\Shop::OUTAPP_SHOP) { $this->_rspErr(1, 'config error shop_id'); return; } if ($goodsMeta['token_type'] != mt\Shop::TOKEN_TYPE_USD) { $this->_rspErr(1, 'config error token_type'); return; } if ($goodsMeta['price'] < 0.0001) { $this->_rspErr(1, 'config error price'); return; } if ($fiat != 'USD') { $this->_rspErr(1, 'paramater error fiat'); return; } if ($fiatAmount + 0.00001 < $goodsMeta['price']) { $this->_rspErr(1, 'paramater error fiatAmount'); return; } if (!in_array($crypto, array( 'CEG', 'ETH' ) )) { $this->_rspErr(1, 'paramater error crypto'); return; } $secretKey = OUTAPP_PKEY; $nowTime = myself()->_getNowTime(); $fiatAmount = $goodsMeta['price']; $orderId = OrderId::gen(); $slat = uniqid(); $params = array( $network, $crypto, $address, $fiat, $fiatAmount, $payWayCode, $country, myself()->_getAccountId(), $orderId, $nowTime, $slat ); foreach ($params as &$value) { $value = '' . $value; } OutAppOrder::add( $orderId, $platform, $goodsId, $goodsMeta['price'], json_encode($params) ); /* 签名方式:将所有的参数用&连接起来做md5加secret_key */ $signStr = implode("&", $params); $sign = md5($signStr . $secretKey); array_push( $params, $sign ); myself()->_rspData( array( 'order_id' => $orderId, 'params' => $params ) ); } public function queryInAppBalance() { myself()->_rspData( array( 'balance' => $this->getInAppBalance() ) ); } public function inappPurchase() { $goodsId = getReqVal('goods_id', 0); $goodsNum = getReqVal('goods_num', 0); $platform = getReqVal('platform', 0); $balance = $this->getInAppBalance(); if ($balance <= 0) { $this->_rspErr(2, "insufficient available balance"); return; } $goodsMeta = mt\ShopGoods::getByGoodsUuid($goodsId); if (!$goodsMeta) { $this->_rspErr(2, "inapp purchase failed"); return; } if (!in_array($goodsMeta['shop_id'], array( mt\Shop::INAPP_SHOP_DIAMOND ) )) { $this->_rspErr(3, "inapp purchase failed"); return; } if ($goodsNum != 1) { $this->_rspErr(3, "goods_num error"); return; } if ($goodsMeta['token_type'] != mt\Shop::TOKEN_TYPE_USD) { $this->_rspErr(3, "token_type config error"); return; } if (!InAppOrder::isValidPlatform($platform)) { $this->_rspErr(1, "error paramater platform"); return; } $price = $goodsMeta['price']; if (empty($price) || $price < 0.001) { $this->_rspErr(1, "config error"); return; } $orderId = OrderId::genInappOrderId(); InAppOrder::add( $orderId, $platform, $goodsId, $price ); InAppRecord::addAmount($price); $this->_rspData(array( 'order_id' => $orderId, )); } public function queryInAppPurchase() { $orderId = getReqVal('order_id', ''); $orderDb = InAppOrder::find($orderId); if (!$orderDb) { myself()->_rspErr(1, 'order not found'); return; } $goodsMeta = mt\ShopGoods::get($orderDb['goods_id']); error_log(json_encode($orderDb)); error_log(json_encode($goodsMeta)); $this->_rspData(array( 'order_id' => $orderDb['order_id'], 'item_id' => $goodsMeta['item_id'], 'item_num' => $goodsMeta['item_num'], 'status' => $orderDb['status'], )); } public function boxPreview() { $goodsId = getReqVal('goods_id', ''); $goodsMeta = mt\ShopGoods::get($goodsId); if (!$goodsMeta) { myself()->_rspErr(1, 'goods not found'); return; } $itemMeta = mt\Item::get($goodsMeta['item_id']); if ($itemMeta['type'] != mt\Item::CHEST_BOX_TYPE) { $this->_rspErr(2, 'goods_id is invalid'); return; } $chestType = $itemMeta['sub_type']; $itemStore = mt\ShopChest::getRandomItemListByChestType($chestType); if (!$itemStore) { $this->_rspErr(2, 'goods_id is invalid'); return; } $record = array(); foreach ($itemStore as $key => $value) { foreach ($value as $k => $v) { if (empty($record[$v['item_id']])) { $record[$v['item_id']] = 0; } $record[$v['item_id']] += 1; } } $this->_rspData( array( 'items' => array_keys($record), 'free_num' => 0, ) ); } private function getCostItemIdByTokenType($tokenType) { switch ($tokenType) { case mt\Shop::TOKEN_TYPE_GOLD: { return V_ITEM_GOLD; } break; case mt\Shop::TOKEN_TYPE_DIAMOND: { return V_ITEM_DIAMOND; } break; default: return -1; } return -1; } private function internalAddItem($awardService, $propertyChgService, $itemMeta, $count ) { switch ($itemMeta['type']) { case mt\Item::HERO_TYPE: { if (empty($grade)) { $grade = 0; } switch ($grade) { case 1: { Hero::addHero1($itemMeta); } break; case 2: { Hero::addHero2($itemMeta); } break; case 3: { Hero::addHero3($itemMeta); } break; default: { Hero::addHero($itemMeta); } break; } $propertyChgService->addHeroChg(); $propertyChgService->addUserChg(); } break; default: { myself()->_addItems( array( array( 'item_id' => $itemMeta['id'], 'item_num' => $count ) ), $awardService, $propertyChgService); } break; } } public function buyGoodsDirect() { error_log('buyGoodsDirect:' . json_encode($_REQUEST)); $cbService = new CallBackService(); $action = 'outappPurchase'; $cbService->dispatch($action); } private function getInAppBalance() { $totalAmount = InAppRecord::getTotalAmount(); $recordDb = InAppRecord::get(); $upLimit = mt\Parameter::getVal('inapp_daily_up_limit', 0); $totalUpLimit = mt\Parameter::getVal('inapp_total_up_limit', 0); $todayAmount = 0; if ($recordDb) { $todayAmount = max($recordDb['amount'], $recordDb['amount_ok']); } $dailyBalance = max(0, $upLimit - $todayAmount); $totalBalance = max(0, $totalUpLimit - $totalAmount); return min($dailyBalance, $totalBalance); } }