123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- <?php
- /**
- * 统一的预创建订单请求对象
- * @version
- * 1.0.0 Created at 2017-12-21. by --gwang
- * @author gwang (mail@wanggangzero.cn)
- * @copyright ? 2017-12-21, SJZ LoyalSoft Corporation & gwang. All rights reserved.
- */
- class PayRequest extends loyalsoft\Object_ext {
- const orderTab = 'tab_order_tab';
- /**
- * @var bool 是否测试(金额降低100倍)(线上版千万别瞎改)
- */
- const isTest = false;
- /**
- * @var string 充值回调透传参数(len=250)
- */
- public $callbackInfo;
- /**
- * 各平台取自己的配置信息
- * @var string 充值回调地址(len=100)
- */
- public $notifyUrl;
- /**
- * @var string 订单ID (len=30)
- */
- public $cpOrderId;
- /**
- * @var float 充值金额 (单位:元) (特:入库时会x100转为分)
- */
- public $amount;
- /**
- * @var string 货币类型(默认:CNY)
- */
- public $currency = 'CNY';
- /**
- * @var string 平台UID
- */
- public $accountId;
- /**
- * @var int 游戏中的分区id
- */
- public $zoneid;
- /**
- * @var string 渠道
- */
- public $channel;
- /**
- * @var string 道具id
- */
- public $product_id;
- /**
- * @var string 道具名称
- */
- public $product_name;
- /**
- *
- * @var string 道具描述
- */
- public $product_desc;
- /**
- * @var string 道具单价
- */
- public $product_price;
- /**
- * @var int (购买)道具数量
- */
- public $product_count;
- /**
- * @var 防沉迷年龄段 ( -1 未实名, 0(0~7) 8(8~16) 16(16~18) 18(18+成年)
- * #[optional]
- */
- public $ageRange = -1;
- /**
- * @var string 公会id
- */
- public $party_id;
- public $party_name;
- /**
- * @var string 签名算法, 目前固定为MD5
- */
- public $signType = "MD5";
- /**
- *
- * @var string MD5(签名内容+apiKey)
- */
- public $sign;
- /**
- * @var string 客户端版本号
- */
- public $clientVer;
- /**
- * @var int 订单编号
- */
- private $order_id;
- /**
- *
- * @return array 订单写入数据库
- */
- public function InserDataBase() {
- // return false; # 2019.10.9 关闭充值
- if (self::isTest) {
- $this->channel = 'tester'; # 测试
- }
- $arr = get_object_vars($this); # 转为数组
- $arr["uid"] = $arr["accountId"]; # 转换下变量名称
- $arr["amount"] = $arr["amount"] * 100; # 拉起平台时传的单位是元,比如UC还有易接,而游戏后台存储的是分
- unset($arr["signType"]); # 毙掉后台不需要的数据
- unset($arr["sign"]);
- unset($arr["accountId"]);
- unset($arr['order_id']);
- unset($arr['ageRange']);
- unset($arr['product_desc']);
- unset($arr['clientVer']);
- $n = loyalsoft\daoInst()->update(self::orderTab)
- ->data($arr)
- ->where('id')->eq($this->order_id)
- ->exec();
- return $n == 1;
- }
- /**
- * @return array 拉取签名参数数组
- */
- public function uc_GetData2Sign() {
- $sid = array('callbackInfo', 'amount', 'notifyUrl', 'cpOrderId', 'accountId');
- $arr = array();
- foreach (get_object_vars($this) as $key => $value) {
- if (in_array($key, $sid)) {
- $arr[$key] = $value;
- }
- }
- return $arr;
- }
- /**
- * @return array 普通返回值数组
- */
- public function retData() {
- $sid = array('callbackInfo', 'amount', 'product_price', 'product_count', 'notifyUrl', 'cpOrderId');
- $arr = array();
- foreach (get_object_vars($this) as $key => $value) {
- if (in_array($key, $sid)) {
- $arr[$key] = $value;
- }
- }
- return $arr;
- }
- /**
- * @return array 小七手游订单结构(未签名)
- * @deprecated since version 0 已废弃
- */
- public function x7sy_retData() {
- $ret = array(
- 'extends_info_data' => $this->callbackInfo, // // 透传参数
- 'game_area' => $this->zoneid,
- 'game_guid' => $this->accountId,
- 'game_level' => 0,
- 'game_orderid' => $this->cpOrderId,
- 'game_price' => $this->product_price, // // 对方要求单位:元
- 'game_role_id' => "no",
- 'game_role_name' => "no",
- 'notify_id' => "3788", // // 如果只有一个可以设置为-1,但不可以设置为0
- 'subject' => $this->product_name
- );
- return $ret;
- }
- /**
- * @return array 易接返回值数组
- * @deprecated since version 0 已废弃
- */
- public function yijie_retData() {
- return $this->retData();
- }
- /**
- * 华为 订单通知魔改版
- * @param type $params 参考:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
- */
- static function From_HW($params) {
- $infoArr = array();
- \loyalsoft\CLog::pay($params);
- $callbackInfo = $params['developerPayload'];
- $infos = explode(',', $callbackInfo); # uid,zoneid,cpOrderId,productId
- $infoArr['orderId'] = $params['orderId'];
- $infoArr['accountId'] = $infos[0]; # uid
- $infoArr['amount'] = number_format($params['price'] / 100, 2, '.', ''); # 分转元 # 华为给过来是分, 这里先转换为元, 入库时再统一以分为单位
- $infoArr['currency'] = $params['currency']; # 如果是海外会有不同的货币类型
- $infoArr['product_id'] = $params['productId'];
- $infoArr['product_count'] = 1;
- $infoArr['channel'] = "huawei"; # 华为
- $infoArr['zoneid'] = (int) $infos[1]; # 分区信息
- $infoArr['callbackInfo'] = $callbackInfo;
- $o = new payRequest($infoArr);
- $o->cpOrderId = $infos[2]; # 重新修订下cpOrderId
- return $o;
- }
- public function __construct($arg = null) {
- parent::__construct($arg);
- if (!$this->accountId || !$this->product_id || !$this->amount || !$this->channel) {
- \loyalsoft\CLog::pay('参数缺失');
- exit('{"err":1,"msg":"参数缺失!"}');
- }
- $this->callbackInfo = $this->accountId . "," . $this->zoneid;
- if (self::isTest) {
- $this->amount *= 0.01; // 也可以改成固定值 0.01, 更省钱些.
- }
- if (!self::isTest and $this->amount) {
- new loyalsoft\Req(null); # 初始化
- \loyalsoft\req()->CV = $this->clientVer; # 设定配置数据版本号(2024.12增补)
- // var_dump(loyalsoft\req()->CV);
- $itemMo = loyalsoft\GameConfig::shop_getItem($this->product_id);
- if (null != $itemMo && $this->amount != $itemMo->price) {
- \loyalsoft\CLog::pay($this->product_id);
- // \loyalsoft\CLog::pay(var_export(loyalsoft\gMem()));
- \loyalsoft\CLog::pay(loyalsoft\GameConfig::shop_getItem($this->product_id)->price);
- \loyalsoft\CLog::pay('金额不符: ' . $this->amount . " <=> " . $itemMo->price);
- exit('{"err":1,"msg":"金额不符!"}');
- }
- }
- loyalsoft\daoInst()->insert(self::orderTab) # 创建一个新的订单
- ->data(array('order_ts' => loyalsoft\now()))
- ->exec();
- $this->order_id = loyalsoft\daoInst()->select('last_insert_id() as id')->fetch('id'); # 取刚才创建的订单的自增id
- $this->cpOrderId = LoyalsoftAPPID . \date('ymdHi') . substr(sprintf("%1$06d", $this->order_id), -6); # 商户唯一id(尾部附加自增id后6位数)
- $this->callbackInfo .= "," . $this->cpOrderId; # 将cpOrderId追加到透传参数中
- $this->notifyUrl = $this::get_notify_url(); # 自动提取支付回调地址
- }
- /**
- * PS. 仅限pay.php作为入口使用才行
- * @return string 获取支付回调地址,
- */
- public function get_notify_url() {
- $url = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER["REQUEST_URI"];
- switch ($this->getPlatStr()) {
- case "hykb":
- $nurl = substr($url, 0, strpos($url, "pay.php")) . "notify_hykb.php";
- break;
- default:
- $nurl = substr($url, 0, strpos($url, "pay.php")) . "notify.php";
- break;
- }
- return $nurl; # 回调地址
- }
- /**
- * 未成年检查 (国内版)
- * @return type
- */
- public function AntiAdditionCheck() {
- $uid = $this->accountId;
- $ageRange = $this->ageRange;
- $ageRange = 18;
- $amt = $this->amount;
- if (isset($uid) && isset($ageRange)) {
- $monthTS = loyalsoft\TimeUtil::tsMonthBegin(); # 本月初起始时间戳
- $dayTS = loyalsoft\TimeUtil::tsDayBegin(); # 当天起始时间戳
- $monthTotal = loyalsoft\daoInst()
- ->select("sum(`amount`)/100 as total") # 总金额(单位:分转元)
- ->from(self::orderTab)
- ->where("uid")->eq($uid) # 该玩家
- ->andWhere("status")->eq(1) # 成交订单
- ->andWhere("order_ts")->ge($monthTS) # 本月
- ->fetch('total');
- if (!is_numeric($monthTotal)) {
- $monthTotal = 0;
- }
- $dayTotal = loyalsoft\daoInst()
- ->select("sum(`amount`)/100 as total") # 总金额(单位:分转元)
- ->from(self::orderTab)
- ->where("uid")->eq($uid) # 该玩家
- ->andWhere("status")->eq(1) # 成交订单
- ->andWhere("order_ts")->ge($dayTS) # 今日
- ->fetch('total');
- if (!is_numeric($dayTotal)) {
- $dayTotal = 0;
- }
- if ($ageRange < 0 || !is_numeric($ageRange)) {
- return \payResp::err(1, "未完成实名认证的用户暂不提供充值.");
- } else if ($ageRange < 8) {
- return \payResp::err(1, "未满8周岁的用户暂不提供充值.");
- } else if ($ageRange < 16) { # 单笔/每月: 50,200
- if ($amt > 50) {
- return \payResp::err(1, "单笔充值金额不高于50¥");
- }
- // if (($amt + $dayTotal) > 100) {
- // return \Resp::err(1, "单日累计充值金额不高于100¥");
- // }
- if (($amt + $monthTotal) > 200) {
- return \payResp::err(1, "当月累计充值金额不高于200¥");
- }
- } else if ($ageRange < 18) { # 单笔/每月: 100,400
- if ($amt > 100) {
- return \payResp::err(1, "单笔充值金额不高于100¥");
- }
- // if (($amt + $dayTotal) > 100) {
- // return \Resp::err(1, "单日累计充值金额不高于100¥");
- // }
- if (($amt + $monthTotal) > 400) {
- return \payResp::err(1, "当月累计充值金额不高于400¥");
- }
- }
- return \payResp::ok("ok");
- }
- return \payResp::err(-1, "参数不足"); # 其他情况
- }
- /**
- * 获得用户的平台字符串
- * @return string
- */
- function getPlatStr() {
- if (strrpos($this->accountId, '_') > 0) {
- return substr($this->accountId, strrpos($this->accountId, '_') + 1); # 提取平台字符串
- } else {
- return "";
- }
- //PS. substr() 函数返回字符串的一部分 strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。
- }
- /**
- * 获得用户的平台唯一id.
- * @return string
- */
- public function getPlatOid() {
- return substr($this->accountId, 0, strrpos($this->accountId, '_')); # 提取平台字符串
- //PS. substr() 函数返回字符串的一部分 strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。
- }
- }
|