This commit is contained in:
aozhiwei 2023-07-31 10:48:09 +08:00
commit f7cf1d91c3
15 changed files with 1079 additions and 785 deletions

View File

@ -85,20 +85,6 @@ class Shop(object):
['status', 0, '订单状态 0:未支付 1:已支付 2:支付失败'],
]
},
{
'name': 'getPayMethods',
'desc': '获取支付方式',
'group': 'Shop',
'url': 'webapp/index.php?c=Shop&a=getPayMethods',
'params': [
_common.ReqHead(),
['token_type', 0, "选用币种"],
],
'response': [
_common.RspHead(),
['!pay_methods', [_common.PayMethod()], '支付方式列表'],
]
},
{
'name': 'boxPreview',
'desc': '宝箱道具预览',

View File

@ -1278,6 +1278,64 @@ CREATE TABLE `t_user_honor` (
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `t_inapp_order`
--
DROP TABLE IF EXISTS `t_inapp_order`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_inapp_order` (
`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`order_id` varchar(60) NOT NULL DEFAULT '' COMMENT '订单id',
`sp_order_id` varchar(64) DEFAULT NULL COMMENT 'app store order_id',
`platform` int(11) NOT NULL DEFAULT '0' COMMENT '0: ios 1: android',
`account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '申请账号id',
`address` varchar(60) DEFAULT NULL COMMENT '申请时账号绑定的钱包',
`item_id` int(11) NOT NULL DEFAULT '0' COMMENT '物品id',
`item_num` bigint(20) NOT NULL DEFAULT '0' COMMENT '物品数量',
`price` bigint(20) NOT NULL DEFAULT '0' COMMENT '价格',
`status` int(11) NOT NULL DEFAULT '0' COMMENT 'status',
`createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间',
PRIMARY KEY (`idx`),
UNIQUE KEY `order_id` (`order_id`),
UNIQUE KEY `platform_sp_order_id` (`platform_sp_order_id`),
KEY `account_id` (`account_id`),
KEY `address` (`address`),
KEY `sp_order_id` (`sp_order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `t_outapp_order`
--
DROP TABLE IF EXISTS `t_outapp_order`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_outapp_order` (
`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',
`order_id` varchar(60) NOT NULL DEFAULT '' COMMENT '订单id',
`sp_order_id` varchar(64) DEFAULT NULL COMMENT 'app store order_id',
`platform` int(11) NOT NULL DEFAULT '0' COMMENT '0: ios 1: android',
`account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '申请账号id',
`address` varchar(60) DEFAULT NULL COMMENT '申请时账号绑定的钱包',
`item_id` int(11) NOT NULL DEFAULT '0' COMMENT '物品id',
`item_num` bigint(20) NOT NULL DEFAULT '0' COMMENT '物品数量',
`price` bigint(20) NOT NULL DEFAULT '0' COMMENT '价格',
`status` int(11) NOT NULL DEFAULT '0' COMMENT 'status',
`createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间',
PRIMARY KEY (`idx`),
UNIQUE KEY `order_id` (`order_id`),
UNIQUE KEY `platform_sp_order_id` (`platform_sp_order_id`),
KEY `account_id` (`account_id`),
KEY `address` (`address`),
KEY `sp_order_id` (`sp_order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
/*!40101 SET character_set_client = @saved_cs_client */;
DROP TABLE IF EXISTS `t_web2_order`;
CREATE TABLE `t_web2_order` (
`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id',

View File

@ -281,6 +281,53 @@ class BlockChainController extends BaseAuthedController {
}
}
public function buyDiamond()
{
$num = getReqVal('num', 0);
if (!is_numeric($num)) {
$this->_rspErr(1, "num is invalid, {$num}");
return;
}
if ($num <= 0) {
$this->_rspErr(1, "num is invalid, {$num}");
return;
}
$price = $this->normalizeWeb3Price($num);
$item_id = V_ITEM_DIAMOND;
$item_count = $num;
error_log("buy diamond start " . $num);
$response = services\BlockChainService::gameItemMallBuy(
Transaction::BUY_GOODS_ACTION_TYPE,
$price,
$item_id,
$item_count
);
BcOrder::upsert($response['trans_id'], array(
'item_id' => $item_id,
'item_num' => $item_count,
'order_type' => 1,
'price' => $num,
'ext_data' => json_encode(array(
'mode' => SHOP_BUY_MODE_NORMAL,
)),
));
$response['item_id'] = $item_id;
$response['item_num'] = $item_count;
error_log("buy diamond, item_id = " . $item_id . " item_count = " . $item_count . " num = " . $num . " price = " . $price . " response = " . json_encode($response));
$this->_rspData(
array(
"block_chain" => $response
)
);
}
private static function getWeb3ServiceUrl()
{
if (SERVER_ENV == _TEST) {

View File

@ -5,37 +5,17 @@
需要对web3service回调的做签名校验!!!
*/
class CallbackController extends BaseController {
require_once('services/CallBack.php');
private $handlers = array(
'mintNftHero' => 'MintNftHero' ,
'gameItemMallBuyOk' => 'GameItemMallBuyOk',
'gameItemMarketBuyOk' => 'GameItemMarketBuyOk',
'MarketSellOrderOk' => 'MarketSellOrderOk',
'MarketBuyOrderOk' => 'MarketBuyOrderOk',
'MarketCancelOrderOk' => 'MarketCancelOrderOk',
'MarketPriceUpdateOrderOk' => 'MarketPriceUpdateOrderOk',
'ShopBuyGoodsDirect' => 'ShopBuyGoodsDirect',
//'ShopInappPurchaseDiamonds' => 'ShopInappPurchaseDiamonds',
);
use services\CallBackService;
class CallbackController extends BaseController {
public function dispatch()
{
error_log("CallbackController Begin");
$cbService = new CallBackService();
$action = getReqVal('action', '');
if (key_exists($action, $this->handlers)) {
error_log("Callback:dispatch____". json_encode($_REQUEST));
$this->internalDispatch($this->handlers[$action]);
} else {
$this->_rspErr(500, 'not found');
}
}
private function internalDispatch($className)
{
require_once ('services/callback/' . $className . '.php');
$obj = eval("return new services\\" . $className . "();");
$obj->process();
$cbService->dispatch($action);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
<?php
namespace models;
use mt;
use phpcommon\SqlHelper;
class InAppOrder extends BaseModel {
const PENDING_STATE = 0;
const FINISHED_STATE = 1;
const FAILED_STATE = 2;
public static function find($orderId) {
$row = SqlHelper::ormSelectOne(
myself()->_get(),
't_inapp_order',
array(
'order_id' => $orderId,
)
);
return $row;
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace models;
use mt;
use phpcommon\SqlHelper;
class OutAppOrder extends BaseModel {
const PENDING_STATE = 0;
const FINISHED_STATE = 1;
const FAILED_STATE = 2;
public static function find($orderId)
{
$row = SqlHelper::ormSelectOne(
myself()->_get(),
't_outapp_order',
array(
'order_id' => $orderId,
)
);
return $row;
}
public static function markFinished($orderId)
{
SqlHelper::update(
myself()->_get(),
't_outapp_order',
array(
'order_id' => $orderId,
),
array(
'state' => self::FINISHED_STATE,
)
);
}
public static function markFailed($orderId)
{
SqlHelper::update(
myself()->_get(),
't_outapp_order',
array(
'order_id' => $orderId,
),
array(
'state' => self::FAILED_STATE,
)
);
}
}

View File

@ -149,4 +149,5 @@ class ShopBuyRecord extends BaseModel
return $row['account_id'];
}
}

View File

@ -6,6 +6,44 @@ use phpcommon;
class Shop {
const TOKEN_TYPE_GOLD = '0';
const TOKEN_TYPE_CEG = '1';
const TOKEN_TYPE_CEC = '2';
const TOKEN_TYPE_BCEG = '3';
const TOKEN_TYPE_DIAMOND = '4';
const TOKEN_TYPE_USDT = '11';
const TOKEN_TYPE_USDC = '12';
const TOKEN_TYPE_BUSD = '13';
const TOKEN_TYPE_MATIC = '101';
const TOKEN_TYPE_BNB = '102';
//99 = 美元
const TOKEN_TYPE_USD = '99';
//21 = 印尼
const TOKEN_TYPE_IDR = '21';
//22 = 菲律宾
const TOKEN_TYPE_PHP = '22';
//23 = 越南
const TOKEN_TYPE_VND = '23';
//24 = 泰国
const TOKEN_TYPE_THB = '24';
//25 = 马来西亚
const TOKEN_TYPE_MYR = '25';
//26 = 日本
const TOKEN_TYPE_JPY = '26';
//27 = 韩国
const TOKEN_TYPE_KRW = '27';
// 限购类型
const DAILY_BUY_LIMIT = 1;
const WEEKLY_BUY_LIMIT = 2;
const TOTAL_BUY_LIMIT = 3;
const INAPP_SHOP = 9;
const OUTSIDE_SHOP = 100;
public static function get($id)

View File

@ -12,6 +12,11 @@ class ShopGoods
return getXVal(self::getMetaList(), $id);
}
public static function getByGoodsUuid($goodsUuid)
{
return getXVal(self::getMetaList(), $goodsUuid);
}
public static function getGoodsList($shopId)
{
self::mustBeShopGoodsHash();

View File

@ -0,0 +1,39 @@
<?php
namespace services;
class CallBackService extends BaseService {
private $handlers = array(
'mintNftHero' => 'MintNftHero' ,
'gameItemMallBuyOk' => 'GameItemMallBuyOk',
'gameItemMarketBuyOk' => 'GameItemMarketBuyOk',
'MarketSellOrderOk' => 'MarketSellOrderOk',
'MarketBuyOrderOk' => 'MarketBuyOrderOk',
'MarketCancelOrderOk' => 'MarketCancelOrderOk',
'MarketPriceUpdateOrderOk' => 'MarketPriceUpdateOrderOk',
'inappPurchase' => 'InAppPurchase',
'outappPurchase' => 'OutAppPurchase',
);
public function dispatch($action)
{
error_log("CallbackController Begin");
if (key_exists($action, $this->handlers)) {
error_log("Callback:dispatch____". json_encode($_REQUEST));
$this->internalDispatch($this->handlers[$action]);
} else {
myself()->_rspErr(500, 'not found');
die();
}
}
private function internalDispatch($className)
{
require_once ('services/callback/' . $className . '.php');
$obj = eval("return new services\\" . $className . "();");
$obj->process();
die();
}
}

View File

@ -0,0 +1,195 @@
<?php
namespace services;
require_once('mt/ShopGoods.php');
require_once('mt/Item.php');
require_once('models/ShopBuyRecord.php');
require_once('models/Hero.php');
require_once('models/HeroSkin.php');
require_once('models/GunSkin.php');
use phpcommon;
use models\ShopBuyRecord;
use models\Hero;
use models\HeroSkin;
use models\GunSkin;
class ShopService {
public static function getGoodsList($shopId)
{
if ($shopId == 0) {
$goodsMetaList = mt\ShopGoods::all();
} else {
$goodsMetaList = mt\ShopGoods::getGoodsList($shopId);
}
$goodsMetaList = $goodsMetaList ? $goodsMetaList : array();
$buyRecordHash = ShopBuyRecord::allToHash();
$goodsList = array();
foreach ($goodsMetaList as $goodsMeta) {
$goodsDto = array(
'goods_meta' => self::goodsMetaToInfo($goodsMeta),
'bought_times' => 0,
'free_num' => 0,
);
array_push($goodsList, $goodsDto);
switch ($goodsMeta['limit_type']) {
case mt\Item::DAILY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goodsMeta['id']);
$goodsDto['bought_times'] = $buyRecord ? $buyRecord['this_day_buy_times'] : 0;
}
break;
case mt\Item::WEEKLY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goodsMeta['id']);
$goodsDto['bought_times'] = $buyRecord ? $buyRecord['this_week_buy_times'] : 0;
}
break;
case mt\Item::TOTAL_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goodsMeta['id']);
$goodsDto['bought_times'] = $buyRecord ? $buyRecord['total_buy_times'] : 0;
}
break;
default: {
}
break;
}
$goodsId = $goodsMeta['goods_id'];
$itemMeta = mt\Item::get($goodsId);
if ($itemMeta) {
// 如果是皮肤,判断是否已经拥有,如果已经拥有,不能购买
if ($itemMeta['type'] == mt\Item::HERO_SKIN_TYPE) {
$errCode = 0;
$errMsg = '';
if (!self::canBuy($itemMeta, $errCode, $errMsg)) {
$goods['bought_times'] = 1;
} else {
$goods['bought_times'] = 0;
}
}
} else {
// error !!!!!!
error_log('item not found:' . $goodsId);
}
if (!empty($goods['free_type'])) {
$count = self::getFreeBuyTimes($goodsMeta['free_type'],
$goodsMeta['id'],
$goodsMeta['goods_id']);
$goodsDto['free_num'] = $goodsDto['free_num'] - $count;
}
}
return $goodsList;
}
public static function getFreeBuyTimes()
{
return 0;
switch ($free_type) {
case 1: {
$dayTime = myself()->_getNowDaySeconds();
$sql = 'SELECT COUNT(idx) as cnt FROM t_shop_free_record WHERE account_id = ? AND `id` = ? AND goods_id = ? AND createtime >= ?';
$row = $conn->execQueryOne($sql, array($account, $id, $goodsId, $dayTime));
return $row['cnt'];
}
break;
}
return 0;
}
public static function buyLimitCheck($goodsMeta, &$errCode, &$errMsg)
{
$errCode = 0;
$errMsg = '';
$buyRecordHash = ShopBuyRecord::allToHash();
$boughtTimes = 1;
{
switch ($goodsMeta['limit_type']) {
case ShopController::DAILY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['this_day_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'this_day_buy_times', 0) >= $goodsMeta['limit_num']) {
$this->_rspErr(2, 'Daily purchase limit');
return;
}
}
break;
case ShopController::WEEKLY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['this_week_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'this_week_buy_times', 0) >= $goodsMeta['limit_num']) {
$this->_rspErr(2, 'Weekly purchase limit reached');
return;
}
}
break;
case ShopController::TOTAL_BUY_LIMIT: {
// error_log("total buy limit " . $address . " " . $id . " " . $goodsMeta['limit_num']);
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $goodsMeta['limit_num']) {
$this->_rspErr(2, 'Purchase limit reached');
return;
}
}
break;
default: {
}
break;
}
}
}
public static function goodsMetaToInfo($goodsMeta)
{
return array(
);
}
private static function canBuy($itemMeta, &$errCode, &$errMsg)
{
$errCode = 0;
$errMsg = '';
switch ($itemMeta['type']) {
case mt\Item::HERO_TYPE: {
$heroDb = Hero::find($itemMeta['id']);
if ($heroDb) {
$errCode = 10;
$errMsg = 'You already have the hero';
return false;
}
}
break;
case mt\Item::HERO_SKIN_TYPE: {
$heroSkinDb = HeroSkin::find($itemMeta['id']);
if ($heroSkinDb) {
$errCode = 10;
$errMsg = 'You already have the skin';
return false;
}
}
break;
case mt\Item::GUN_SKIN_TYPE: {
$gunSkinDb = GunSkin::find($itemMeta['id']);
if ($gunSkinDb) {
$errCode = 10;
$errMsg = 'You already have the skin';
return false;
}
}
break;
default: {
return true;
}
break;
}
return true;
}
}

View File

@ -0,0 +1,207 @@
<?php
namespace services;
require_once("mt/ShopGoods.php");
require_once("mt/Item.php");
require_once("models/ShopBuyRecord.php");
require_once("services/LogService.php");
require_once("ShopAddItemService.php");
use phpcommon\SqlHelper;
use mt\ShopGoods;
use mt\Item;
use models\ShopBuyRecord;
use services\LogService;
class InAppPurchase {
public function process()
{
error_log('ShopInappPurchaseDiamonds:' . json_encode($_REQUEST, JSON_PRETTY_PRINT));
error_log('----- inappPurchaseDiamonds -----');
$body = json_decode(file_get_contents('php://input'), true);
error_log('body:' . json_encode($body));
$channel = $body['channel'];
$records = $body['records'];
$sign = $body['sign'];
// {
// channel: 'google',
// sign: '123456677' // 签名字段
// records: [{
// productId: '2999', // 从google play console获取的product id
// gameOrderId: '1231321312', // 开始支付时, 从游戏相关服务那获得的订单id
// orderId: 'GPA.3355-1172-9416-16839', // 从google develope API 获取的订单id
// status: 9, // 订单状态, 上报的订单状态一般只有2种情况, 9: 支付成功, 96: 用户退款
// }]
// }
// let reportData: any = {
// channel: 'google',
// records,
// }
// const hashSort = ''
// const signStr = 'channel=google&' + records.map(record =>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::productDiamond(['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::productDiamond(['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();
}
}

View File

@ -16,8 +16,8 @@ use models\ShopBuyRecord;
use services\LogService;
class ShopBuyGoodsDirect
{
class OutAppPurchase {
public function process()
{
error_log("buyGoodsDirect --- " . json_encode($_REQUEST));

View File

@ -0,0 +1,168 @@
<?php
namespace services;
require_once("mt/ShopGoods.php");
require_once("mt/Item.php");
require_once("models/ShopBuyRecord.php");
require_once("models/OutAppOrder.php");
require_once("services/LogService.php");
require_once("ShopAddItemService.php");
use phpcommon\SqlHelper;
use models\ShopBuyRecord;
use models\OutAppOrder;
use services\LogService;
/*
// let repdata = {
// account_id: string
// order_id: string
// status: string
// id: string
// txhash: string
// }
// 我返回给你这些数据和一个sign字段,
// sign使用上面 repdata 按key 顺序排后, 组成key1=val1&key2=val2后, 使用hmac_sha256 hash, key是
// PENDING = 0, // 初始状态
// TRANSFERING = 1, //只有国库模式才会有该状态
// TRANSFERED = 2, //只有国库模式才会有该状态
// SUCCESS = 9, // 成功的最终状态
// TRANSFER_FAIL = 98, // 转账错误
// FAIL = 99, // 也是错误
//
*/
class OutAppPurchase {
public function process()
{
error_log("OutAppPurchase --- " . json_encode($_REQUEST));
if (!$this->verifySign()) {
error_log("verifySign error --- " . json_encode($_REQUEST));
myself()->_rspErr(1, 'verifySign error');
return;
}
$accountId = getReqVal('account_id', '');
$status = getReqVal('status', '');
$id = getReqVal('id', '');
$txhash = getReqVal('txhash', '');
$sign = getReqVal('sign', '');
$orderId = getReqVal('order_id', '');
$orderDb = OutAppOrder::find($orderId);
if (!$orderDb) {
myself()->_rspErr(2, 'not found order');
return;
}
if ($orderDb['status'] != OutAppOrder::FINISHED_STATE) {
myself()->_rspErr(0, 'order is finished');
return;
}
OutAppOrder::markFinished($orderDb['order_id']);
$orderDb = OutAppOrder::find($orderId);
if (!$orderDb) {
myself()->_rspErr(2, 'not found order');
return;
}
if ($orderDb['status'] == OutAppOrder::FINISHED_STATE) {
myself()->_rspErr(0, 'order is finished');
return;
}
$buyStatus = 0; // 1: 成功, 2: 失败
switch ($status) {
case "9":
$buyStatus = 1;
// 充值成功,开始首充奖励
$this->beginFirstTupop($address);
break;
case "99":
case "98":
$buyStatus = 2;
break;
default:
error_log("buyGoodsDirect--- " . $order_id . " --- " . $status);
$this->_rspErr(1, "status error, status: {$status}");
break;
}
if ($buyStatus == 2) {
$this->_rspErr(2, "buyStatus error, buyStatus: {$buyStatus}");
return;
}
// 以下是看商品表中是否配置了充值额外奖励
$goodsMeta = mt\ShopGoods::get($orderDb['goods_id']);
$goodsNum = $orderDb['goods_num'];
$bundleSize = $goodsMeta['bonus_num'] ? $goodsMeta['bonus_num'] : 0;
$itemNum = $goodsNum * $bundleSize;
$itemId = $goodsMeta['bonus'];
$meta = mt\Item::get($itemId);
if ($meta && $itemNum > 0) {
if ($itemId == V_ITEM_DIAMOND) {
$event = [
'name' => LogService::RECHARGE_CEBG_BONUS,
'val' => $itemNum
];
LogService::productDiamondCallback(
array(
'account_id' => $orderDb['account_id']
),
$event);
}
error_log("buyGoodsDirect---" . $address . "---" . $itemId . "---" . $itemNum);
$this->_addGoods($address, array(
'goods_id' => $itemId,
'goods_num' => $itemNum,
'id' => $id,
));
}
$this->_rspOk();
}
private function beginFirstTupop($address)
{
$conn = myself()->_getMysql('');
$exist = SqlHelper::selectOne(
$conn,
't_first_topup',
array('address'),
array('address' => $address)
);
if ($exist) {
return;
}
// 开始首充奖励活动进程
$chk = SqlHelper::insert(
$conn,
't_first_topup',
array(
'address' => $address,
'createtime' => myself()->_getNowTime(),
'status1' => 0,
'status2' => 0,
'status3' => 0,
)
);
if (!$chk) {
return;
}
}
private function verifySign()
{
}
}