function payAction() { $request = $this->getRequest(); if ('POST' == $request->getMethod()) { $ssotoken = $this->post()->get("ssotoken"); $payType = $this->post()->get("payType"); $resource = $this->post()->get("resource"); $amt = $this->post()->get("amt"); $coinId = $this->post()->get("coinId"); $platform = $this->post()->get("channel"); $schoolId = $this->post()->get("schoolId"); } else { $ssotoken = $this->get("ssotoken"); $payType = $this->get("payType"); $resource = $this->get("resource"); $amt = $this->get("amt"); $coinId = $this->get("coinId"); $platform = $this->get("channel"); $schoolId = $this->get("schoolId"); } //此处为测试数据 //$resource = []; $resource = json_decode($resource, true); //接收参数判断 if (!$ssotoken || !$payType || !$amt) { $this->displayJsonUdo(Common_Error::ERROR_PARAM, "", "缺少必选参数"); } $courseCount = 0; $schoolModel = new SchoolModel(); //余额支付时,需对resource参数进行判断 if ($payType == Common_Config::UDO_PAYTYPE_COIN || $payType == Common_Config::UDO_PAYTYPE_CREDIT) { if (!is_array($resource) || !$schoolId) { $this->displayJsonUdo(Common_Error::ERROR_PARAM, "", "缺少resource或schoolId参数"); } //从客户端传过来的resource是所有选中的资源 //此处根据resource生成交易的信息 //$resourceType = 0; $resourceInfo = ""; $courseName = ""; foreach ($resource as $k => $value) { if ($value['resourceType'] == Common_Config::UDO_RESOURCE_COURSE) { $courseCount++; //$resourceType = Common_Config::UDO_RESOURCE_SCHOOL; $resourceInfo = "频道"; $courseName = $courseName ? $courseName : $schoolModel->getSingleCourse($value['resourceId']); } } $resourceInfo = $courseName['name'] . "'等" . $courseCount . "个课程"; } elseif ($payType == Common_Config::UDO_PAYTYPE_RECHARGE) { if (!$coinId || !$platform) { $this->displayJsonUdo(Common_Error::ERROR_PARAM, "", "缺少channel或coinId参数"); } } $accountModel = new AccountModel(); $tradeModel = new TradeModel(); $userModel = new UserModel(); //在校验过参数完整性后,生成订单 $uid = $userModel->getUserId($ssotoken); if (is_array($uid)) { $this->displayJsonUdo(Common_Error::INVALID_TOKEN, "", $uid['msg']); } $order = $accountModel->newOrder($ssotoken, $uid, $schoolId, $courseCount, $payType, $resource, $coinId, $amt, $platform); //对生成订单的结果进行判断 if ($order < 0) { $this->displayJsonUdo(Common_Error::ERROR_SUCCESS, array("result" => $order)); } //生成订单后,将支付参数传向公共云 //根据支付类型不同,在调用公共云的支付服务时,传相应的值处理 /* * @param payType * 1:U币支付 * 2:U币充值 * 3.学分支付 */ switch ($payType) { case Common_Config::UDO_PAYTYPE_COIN: $type = Common_Config::PUBLIC_PAYTYPE_AMOUNT; $subject = "U币购买'" . $resourceInfo; $score = 0; $balanceAmt = $amt; $channel = 0; $chargeAmt = 0; break; case Common_Config::UDO_PAYTYPE_RECHARGE: //客户端提交的amt均为 $type = $type = Common_Config::PUBLIC_PAYTYPE_CHANNEL; $coinMoney = $tradeModel->getCoinMoney($coinId); //实际 $chargeAmt = $amt; $amt = $coinMoney['price']; $subject = "U币充值"; $score = 0; $balanceAmt = 0; $channel = $platform; break; case Common_Config::UDO_PAYTYPE_CREDIT: $type = Common_Config::PUBLIC_PAYTYPE_AMOUNT; $subject = "学分购买'" . $resourceInfo; $score = $amt; $amt = 0; $balanceAmt = 0; $channel = 0; $chargeAmt = 0; break; } //notifyUrl:需腰写在配置文件里 $notifyUrl = Common_Config::PAY_NOTIFY_URL; $remark = "支付"; //公共云传回预下单信息 $result = $accountModel->pay($ssotoken, $type, $subject, $amt, $chargeAmt, $score, $balanceAmt, $channel, $notifyUrl, $remark); switch ($payType) { case Common_Config::UDO_PAYTYPE_COIN: case Common_Config::UDO_PAYTYPE_CREDIT: if ($result) { //支付成功,写入购买关系表,U币和学分变动表 $insertBought = $accountModel->insertBought($uid, $schoolId, $resource, $order, $result['transNo']); $accountModel->insertTransLog($uid, 0 - ($payType == Common_Config::UDO_PAYTYPE_CREDIT ? $score : $amt), $subject, $payType == Common_Config::UDO_PAYTYPE_CREDIT ? Common_Config::CREDIT_LOG : Common_Config::COIN_LOG, $ssotoken, $schoolId); if ($insertBought < 0) { $this->displayJsonUdo(Common_Error::ERROR_SUCCESS, array("result" => $insertBought)); } } //print_r($result); $this->displayJsonUdo(Common_Error::ERROR_SUCCESS, array_merge(array("result" => Common_Error::ERROR_ORDER_SUCCESS), $result)); break; case 2: if (array_key_exists("invoke", $result) && array_key_exists("transNo", $result) && $result['transNo'] && $result['invoke']) { $accountModel->updateOrder($order, $result['transNo'], Common_Config::ORDER_NOT_PAY); $this->displayJsonUdo(Common_Error::ERROR_SUCCESS, array_merge(array("result" => Common_Error::ERROR_ORDER_SUCCESS), array("transNo" => $result['transNo'], "invoke" => $result['invoke']))); } break; } $this->displayJsonUdo(Common_Error::ERROR_FAIL); }
function newOrder($ssotoken, $uid, $schoolId, $courseCount = 0, $payType, $resource = [], $coinId = 0, $amount, $platform = 0, $couponId = 0, $couponAmt = 0) { $tblOrder = new DB_Udo_Order(); $tblSchoolPrice = new DB_Udo_SchoolPrice(); $tblResource = new DB_Sso_Resource(); $tblCoinInfo = new DB_Udo_CoinInfo(); $tblBought = new DB_Udo_UserBought(); $tradeModel = new TradeModel(); $correct = 0; $schoolPrice = $tblSchoolPrice->scalar("priceType,price", "where resourceId = {$schoolId}"); $balance = $this->getSsoBalance($ssotoken); $userModel = new UserModel(); $mobile = $userModel->getUserName($uid)['mobile']; //生成订单前,首先判断资源定价信息是否有误 if ($payType == Common_Config::UDO_PAYTYPE_COIN || $payType == Common_Config::UDO_PAYTYPE_CREDIT) { //如果是频道类型,首先获取频道的定价类型和定价 //根据用户提交过来的参数并不知道是否全部购买了课程 //$resource 获取所有非免费课程 $charge = $tblResource->fetchAll("id", "where entrance_id = {$schoolId} and type = 6 and price_type <> 3 and enabled = 1"); $totalPrice = 0; foreach ($resource as $k => $val) { if ($val['resourceType'] == 1) { continue; } $resourcePrice = $tblResource->scalar("id,type,entrance_id,price_type,cur_price", "where id = {$val['resourceId']}"); $totalPrice += $resourcePrice['cur_price']; //print_r($resourcePrice['price_type']); if ($payType == Common_Config::UDO_PAYTYPE_COIN && $resourcePrice['price_type'] == Common_Config::UDO_PRICETYPE_COIN || $payType == Common_Config::UDO_PAYTYPE_CREDIT && $resourcePrice['price_type'] == Common_Config::UDO_PRICETYPE_CREDIT) { $correct = 1; } else { return Common_Error::ERROR_COURSE_PRICETYPE; } //再判断课程用户是否已经购买 $bought = $tblBought->scalar("id", "where userId ={$uid} and resourceId= {$val['resourceId']} and schoolId = {$schoolId}"); //print_r($bought); if ($bought) { return Common_Error::ERROR_COURSE_BOUGHT; } } //再判断定价值是否正确 //如果传过来的课程数量就是所有需付费的课程,那么总价是频道定价 if (count($charge) == $courseCount) { $totalPrice = $schoolPrice['price']; } if ($amount != $totalPrice) { return Common_Error::ERROR_COURSE_PRICE; } //总价核验后,再核验账户余额 if ($totalPrice > ($payType == Common_Config::UDO_PAYTYPE_COIN ? $balance['amt'] : $balance['score'])) { return Common_Error::ERROR_SHORT_BALANCE; } //在数据核验准确后,生成订单 $newOrder = []; $retry = 0; //如果生成失败会再循环尝试三次 while ($retry <= 3 && !$newOrder) { $newOrder = $tblOrder->insert(array("userId" => $uid, "mobile" => $mobile, "payType" => $payType, "resource" => json_encode($resource), "amount" => $amount, "createTime" => time(), "status" => Common_Config::ORDER_NOT_PAY)); $retry++; //如果第三次仍失败,返回订单创建失败 if ($retry == 3) { return Common_Error::ERROR_ORDER_FAIL; } } return $newOrder; } elseif ($payType == Common_Config::UDO_PAYTYPE_RECHARGE) { $coinInfo = $tblCoinInfo->scalar("amt", "where id = {$coinId}"); if ($amount != $coinInfo['amt']) { return Common_Error::ERROR_COIN_INFO; } //在数据核验准确后,生成订单 $newOrder = []; $retry = 0; $coinMoney = $tradeModel->getCoinMoney($coinId); //如果生成失败会再循环尝试三次 while ($retry <= 3 && !$newOrder) { $newOrder = $tblOrder->insert(array("userId" => $uid, "mobile" => $mobile, "payType" => $payType, "coinId" => $coinId, "money" => $coinMoney['price'], "amount" => $amount, "platform" => $platform, "createTime" => time(), "status" => Common_Config::ORDER_NOT_PAY)); $retry++; //如果第三次仍失败,返回订单创建失败 if ($retry == 3) { return Common_Error::ERROR_ORDER_FAIL; } } return $newOrder; } }