123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- <?php
- namespace loyalsoft\pay;
- /**
- * Description of OrderNotice
- * 通用支付订单通知模型
- * @version
- * 1.0.0 Created at 2017-12-26. by --gwang
- * @author gwang (mail@wanggangzero.cn)
- * @copyright ? 2017-12-26, SJZ LoyalSoft Corporation & gwang. All rights reserved.
- */
- class OrderNotice extends \loyalsoft\Object_ext {
- const orderTab = 'tab_order_tab';
- /**
- * uid,zoneid,cpOrderId
- * @var string 充值回调透传参数(len=250)
- */
- public $callbackInfo;
- /**
- * @var int 充值金额 单位:分
- */
- public $amount;
- /**
- * @var string 货币类型(默认:CNY)
- */
- public $currency = 'CNY';
- /**
- * @var string 订单ID (len=30)
- */
- public $cpOrderId;
- /**
- * @var string 平台UID(不含渠道串)
- */
- public $uid;
- /**
- * @var string 平台字符串
- */
- public $channel;
- /**
- *
- * @var type 订单状态: 0:创建订单,1:支付成功,2: 支付失败
- */
- public $status;
- /**
- *
- * @var type
- */
- protected $sdk_orderid;
- /**
- *
- * @var type
- */
- protected $otherInfo;
- /**
- * @return boolean 校验订单数据
- */
- public function Check() {
- // var_dump($this);
- $dbOrder = $this->dbOrder();
- // var_dump($dbOrder);
- \loyalsoft\CLog::pay('查询订单结果: ' . var_export($dbOrder, TRUE));
- if (!$dbOrder) {
- \loyalsoft\CLog::pay('订单不存在! ' . $this);
- return false;
- }
- if ($dbOrder->status == 1) {
- \loyalsoft\CLog::pay('订单已经完成!' . $this);
- return false;
- }
- // // 提取纯UID作比较
- // $pureUID = function($str) {
- //// var_dump($str);
- // if (!strpos($str, "-")) {
- // return $str;
- // }
- // return substr($str, strpos($str, "-") + 1);
- // };
- //// var_dump($this->uid);
- // if ($pureUID($dbOrder->uid) != $pureUID($this->uid)) {
- // \loyalsoft\CLog::pay('UID校验不匹配! ' . $pureUID($this->uid) . " (" . $pureUID($dbOrder->uid) . ")");
- // return false;
- // }
- if ($dbOrder->amount != $this->amount) {
- \loyalsoft\CLog::pay('金额校验不匹配! ' . $this->amount . " (" . $dbOrder->amount . ")");
- return false;
- }
- return true;
- }
- /**
- * 获取数据库中的订单记录
- * @return \loyalsoft\pay\dbOrder
- */
- public function dbOrder() {
- $dbOrder = \loyalsoft\daoInst()->select()->from(self::orderTab)
- ->where('cpOrderId')->eq($this->cpOrderId)
- ->limit(1)->fetch();
- return $dbOrder;
- }
- /**
- * 检查重复的渠道订单id(目前仅在ios平台做了校验,其他都是后台通知。
- * @return boolean true 验证通过,false 验证失败,已经存在相同的订单id
- */
- public function CheckDuplicateSdkOrder() {
- $n = \loyalsoft\daoInst()->select()->from(self::orderTab)
- ->where('sdk_orderid')->eq($this->sdk_orderid)
- ->count();
- return $n <= 0;
- }
- /**
- * @return boolean 更新订单状态
- */
- public function UpdateOrderStatus() {
- $n = \loyalsoft\daoInst()->update(self::orderTab)
- ->data(array('status' => $this->status,
- 'sdk_orderid' => $this->sdk_orderid,
- 'otherInfo' => $this->otherInfo,
- 'close_ts' => \loyalsoft\now()))
- ->where('cpOrderId')->eq($this->cpOrderId)
- ->exec();
- return $n > 0;
- }
- // <editor-fold defaultstate="collapsed" desc="通知消息转换为统一的Order对象">
- /**
- * 解析华为后台通知数据, 转化为order对象
- * @param type $args https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/server-data-model-0000001050986133#section264617465219
- */
- public static function Parse_hwOrder($args) {
- $o = new OrderNotice();
- $callbackInfo = $args['developerPayload']; # uid,zoneid,cpOrderId,productid # 透传参数: uid,zoneid,cpOrderId
- $infoArr = explode(',', $callbackInfo);
- $o->channel = "huawei"; # 渠道代码
- $o->uid = $infoArr[0];
- $o->cpOrderId = $infoArr[2];
- $o->status = $args['purchaseState'] == 0 ? 1 : 2; # 华为通知中的支付状态: -1初始化, 0 成功, 1 已取消, 2 已撤销或已退款 3 待处理
- $o->amount = $args['price']; # 结算价格
- $o->currency = $args['currency']; # 结算货币类型
- $o->sdk_orderid = $args['orderId']; # 华为后台订单id.
- $o->callbackInfo = $callbackInfo; # 记录下透传信息
- // $o->otherInfo = $args['purchaseToken']; # 当前92位,后续存在扩展可能,如要进行存储,建议您预留128位的长度
- return $o;
- }
- /**
- * 识别UC后台通知数据
- * @param array $args
- * @return \loyalsoft\pay\OrderNotice
- */
- public static function Parse_UcOrder($args) {
- $o = new OrderNotice();
- $o->channel = "uc"; # 渠道代码
- $o->cpOrderId = $args["data"]["cpOrderId"]; # (后台)订单编号
- $o->status = ($args["data"]["orderStatus"] == "S") ? 1 : 2; # 订单状态(九游返回值: S/F)
- $o->uid = $args['data']['accountId']; # 玩家uid
- $o->amount = $args['data']['amount'] * 100; # 支付金额, uc 返回的单位是元
- $o->callbackInfo = $args['data']['callbackInfo']; # uid-uc,zoneid,cpOrderId
- $o->sdk_orderid = $args['orderId']; # UC订单ID
- $o->otherInfo = $args['failedDesc']; # 其他信息
- return $o;
- }
- /**
- * 解析易接后台通知数据
- * @param array $args
- */
- public static function Parse_1SDKOrder($args) {
- $o = new OrderNotice();
- $o->channel = "1sdk"; # 渠道代码
- $ext = explode(',', $args['cbi']);
- $o->cpOrderId = $ext[2]; # 这个字段藏在透传参数中
- $o->status = ($args["st"] == "1") ? 1 : 2; # 订单状态(易接SDK返回值: 1/成功,其他失败)
- $o->uid = $args['uid']; # 玩家uid
- $o->amount = $args['fee']; # 支付金额, 易接返回值单位是分
- $o->callbackInfo = $args['cbi']; # 透传参数, uid-uc,zoneid,cpOrderId
- $o->sdk_orderid = $args['ssid']; # 渠道订单id
- $o->otherInfo = $args['tcd']; # 易接订单id
- return $o;
- }
- /**
- * 生成苹果支付订单数据.
- * @param array $argsClient
- * @param array $receipt 苹果凭证
- */
- public static function reParse_IOSOrder($argsClient, $receipt) {
- $o = new OrderNotice();
- $o->channel = "ios"; # 渠道代码
- $o->uid = $argsClient->uid; # 玩家uid
- $o->cpOrderId = $argsClient->cpOrderId; # 这个字段藏在透传参数中
- $o->callbackInfo = $argsClient->callbackInfo; # 透传参数, uid-uc,zoneid,cpOrderId
- $o->status = ($receipt["status"] == "0") ? 1 : 2; # 订单状态(苹果返回值: 0/成功,其他失败)
- $product_id = $receipt['product_id']; # 道具ID
- $itemModel = \loyalsoft\GameConfig::shop_getItem($product_id); # 道具常量
- $o->amount = $itemModel->price * 100; # 入库单位是分, 后台单位是元
- $o->sdk_orderid = $receipt['transaction_id']; # 交易订单id
- $o->otherInfo = $receipt['purchase_date']; # 购买时间
- return $o;
- }
- /**
- * 解析支付宝通知
- * @param type $args
- * @return \loyalsoft\pay\OrderNotice
- */
- public static function Parse_alipayOrder($args) {
- $o = new OrderNotice();
- $callbackInfo = urldecode($args['passback_params']); # 透传参数(zfb进行过urlencode)
- $exts = explode(',', $callbackInfo);
- $o->channel = "soft"; # 渠道代码zfb?
- $o->cpOrderId = $args['out_trade_no']; # 订单编号(龙游)
- $o->status = ($args["trade_status"] == "TRADE_SUCCESS") ? 1 : 2; # 订单状态()
- $uid = $exts[0];
- $o->uid = $uid; // strpos($uid, '_') > 0 ? substr($uid, 0, strpos($uid, '_')) : $uid; # 玩家uid
- $o->amount = $args['total_amount'] * 100; # 订单金额。本次交易支付的订单金额,单位为人民币(元)。支持小数点后两位。 游戏后台单位是分
- $o->callbackInfo = $callbackInfo; # 透传参数, uid-uc,zoneid,cpOrderId
- $o->sdk_orderid = $args['trade_no']; # 支付宝订单id
- $o->otherInfo = "zfb:" . $args['buyer_logon_id']; # 支付宝登录账户号
- return $o;
- }
- /**
- * 解析微信通知
- * @param type $args
- * @return \loyalsoft\pay\OrderNotice
- */
- public static function Parse_weixinpayOrder($args) {
- $o = new OrderNotice();
- $exts = explode(',', $args['attach']); # 透传参数
- $o->channel = "soft"; # 渠道代码zfb?
- $o->cpOrderId = $args['out_trade_no']; # 订单编号(龙游)
- $o->status = ($args["result_code"] == "SUCCESS") ? 1 : 2; # 订单状态()
- $uid = $exts[0];
- $o->uid = $uid; // strpos($uid, '_') > 0 ? substr($uid, 0, strpos($uid, '_')) : $uid; # 玩家uid
- $o->amount = intval($args['total_fee']); # 支付金额(微信穿过来是分)。 游戏后台单位是分
- $o->callbackInfo = $args['attach']; # 透传参数, uid-uc,zoneid,cpOrderId
- $o->sdk_orderid = $args['transaction_id']; # 微信订单id
- $o->otherInfo = "wx:" . $args['openid']; # 付款者openid
- return $o;
- }
- /**
- * 解析小米通知 2023.6.16
- * @param type $args
- * @return \loyalsoft\pay\OrderNotice
- */
- public static function Parse_mipayOrder($args) {
- $o = new OrderNotice();
- // $exts = explode(',', $args['attach']); # 透传参数
- $o->channel = "mi"; # 渠道代码zfb?
- $o->cpOrderId = $args['cpOrderId']; # 订单编号(龙游)
- $o->status = ($args["orderStatus"] == "TRADE_SUCCESS") ? 1 : 2;
- $uidAry = explode('%2C', $args['cpUserInfo']);
- $uid = $uidAry[0];
- $o->accountId = $uid;
- $o->uid = $uid; # 玩家uid
- $o->amount = intval($args['payFee']); # 支付金额: 游戏后台单位是分
- $o->callbackInfo = str_replace('%2C', ',', $args['cpUserInfo']); # 透传参数, uid,zoneid,cpOrderId
- $o->sdk_orderid = $args['orderId']; # 小米订单id
- $o->otherInfo = "mi(uid):" . $args['uid']; # 付款者openid
- return $o;
- }
- /**
- * 解析应用宝充值通知 2023.5.10
- * @param array $args
- */
- public static function Parse_ysdkOrder($args) {
- $o = new OrderNotice();
- $o->channel = "yyb"; # 渠道代码
- $o->status = 1; # 订单状态(ysdk成功才通知)
- $o->uid = $args['openid']; // openid # 玩家uid(不带_yyb)
- $o->amount = $args['amt']; # 支付金额, 游戏后台统一单位是分
- $appmeta = $args['appmeta']; # 自定义字段*支付方式*平台渠道(qq)
- list($callbackInfo, $payType, $plat) = explode('*', $appmeta); # 提取
- $o->callbackInfo = $callbackInfo; # 透传参数, uid-uc,zoneid,cpOrderId
- list($uid, $zoneid, $cpOrderId) = explode(',', $callbackInfo); # 提取
- $o->cpOrderId = $cpOrderId; # 订单编号
- $o->otherInfo = $plat . ":" . $o->uid; # 手Qor微信的平台串
- return $o;
- }
- /**
- * 解析应用宝充值通知
- * @param array $args
- */
- public static function Parse_yybOrder($args) {
- $o = new OrderNotice();
- $o->channel = "yyb"; # 渠道代码
- $o->cpOrderId = $args['orderId']; # 订单编号
- $o->status = ($args["status"] == "1") ? 1 : 2; # 订单状态(易接SDK返回值: 1/成功,其他失败)
- $o->uid = $args['uid']; // openid # 玩家uid
- $o->amount = $args['amount'] * 100; # 支付金额, 游戏后台统一单位是分
- $o->callbackInfo = $args['extReserved']; # 透传参数, uid-uc,zoneid,cpOrderId
- $o->otherInfo = $args['pf']; # 手Qor微信的平台串
- return $o;
- }
- /**
- * 解析360充值通知
- */
- public static function Parse_360Order($args) {
- $exts = explode(',', $args['app_ext1']);
- $o = new OrderNotice();
- $o->channel = 'qihoo360';
- if (isset($args['app_order_id'])) {
- $o->cpOrderId = $args['app_order_id'];
- } else {
- $o->cpOrderId = $exts[2]; # 第三个参数是cpOrderId
- }
- $o->sdk_orderid = $args['order_id'];
- $o->status = ($args['gateway_flag'] == 'success') ? 1 : 2;
- $o->uid = $args['app_uid'];
- $o->amount = $args['amount']; # 360通知的单位是分,与后台一致
- $o->callbackInfo = $args['app_ext1'];
- $o->otherInfo = $args['user_id'];
- return $o;
- }
- /**
- * 解析vivo充值通知接口
- */
- public static function Parse_vivoOrder($args) {
- $o = new OrderNotice();
- $o->channel = 'vivo';
- $o->cpOrderId = $args['cpOrderNumber'];
- $o->sdk_orderid = $args['orderNumber'];
- $o->status = ($args['tradeStatus'] == '0000') ? 1 : 2;
- $o->uid = $args['uid'];
- $o->amount = $args['orderAmount']; # vivo通知的单位是分, 与游戏后台一致
- $o->callbackInfo = $args['extInfo'];
- $o->otherInfo = 'payTime:' . $args['payTime'];
- return $o;
- }
- /**
- * 解析联想支付通知
- * @param type $args
- */
- public static function Parse_lenovo($args) {
- // var_dump($args);
- $exts = explode(',', $args['cpprivate']);
- $o = new OrderNotice();
- $o->channel = 'lenovo';
- $o->cpOrderId = $args['exorderno'];
- $o->sdk_orderid = $args['transid'];
- $o->status = ($args['result'] == 0) ? 1 : 2;
- $o->uid = $exts[0];
- $o->amount = $args['money'];
- $o->callbackInfo = $args['cpprivate'];
- $o->otherInfo = 'payType:' . $args['paytype'];
- return $o;
- }
- /**
- * 解析金立支付通知
- * @param type $args
- */
- public static function Parse_gionee($args) {
- // var_dump($args);
- $exts = explode(',', $args['ext_info']); # 透传参数
- $o = new OrderNotice();
- $o->channel = 'gionee';
- $o->cpOrderId = $args['out_order_no'];
- // $o->sdk_orderid = $args['transid']; # 金立订单只在创建的时候返回,通知的时候没有╭(╯^╰)╮
- $o->status = 1; # 金立后台只将支付成功的订单进行返回,未成功订单不会有通知
- $o->uid = $exts[0];
- $o->amount = $args['deal_price'] * 100; # 金立后台单位是元, 游戏后台单位是分
- $o->callbackInfo = $args['ext_info'];
- // $o->otherInfo = ''; #
- return $o;
- }
- /**
- * 解析百度支付通知
- * @param type $args
- */
- public static function Parse_Baidu($args) {
- // var_dump($args);
- $o = new OrderNotice();
- $o->channel = 'baidu';
- $o->cpOrderId = $args['CooperatorOrderSerial']; # CP 订单号
- $o->sdk_orderid = $args['OrderSerial']; # SDK订单号
- $Contents = json_decode(base64_decode(urldecode($args['Content']))); # 数据结构
- $o->status = $Contents->OrderStatus == 1 ? 1 : 2; # 0 失败, 1 成功
- $o->uid = $Contents->UID; # UID
- $o->amount = $Contents->OrderMoney * 100; # 百度后台单位是元, 游戏后台单位是分
- $o->callbackInfo = $Contents->ExtInfo; # 透传参数
- $o->otherInfo = '银行到账时间:' . $Contents->BankDateTime # 其他信息
- . ' 代金券金额:' . $Contents->VoucherMoney; #
- return $o;
- }
- /**
- * 解析三星支付通知
- * @param type $args
- */
- public static function Parse_samsung($args) {
- $exts = explode(',', $args['cpprivate']);
- $o = new OrderNotice();
- $o->channel = 'samsung';
- if (isset($args['cporderid'])) {
- $o->cpOrderId = $args['cporderid'];
- } else {
- $o->cpOrderId = $exts[2]; // uid,zoneid,cporderid
- }
- $o->sdk_orderid = $args['transid']; // 平台流水号
- $o->status = ($args['result'] == 0) ? 1 : 2;
- $o->uid = $args['appuserid'];
- $o->amount = $args['money'] * 100; // float 单位:元, Ps.游戏后台是分
- $o->callbackInfo = $args['cpprivate'];
- $o->otherInfo = 'transtype:' . $args['transtype']; // 交易类型
- return $o;
- }
- /**
- * 解析小七手游支付通知
- * @param type $args
- */
- public static function Parse_x7sy($args) {
- $exts = explode(',', $args['extends_info_data']);
- $o = new OrderNotice();
- $o->channel = 'x7sy';
- if (isset($args['game_orderid'])) { // cpOrder
- $o->cpOrderId = $args['game_orderid'];
- } else {
- $o->cpOrderId = $exts[2]; // uid,zoneid,cporderid
- }
- $o->sdk_orderid = $args['xiao7_goid']; // 渠道流水号
- $o->status = 1; //($args['result'] == 0) ? 1 : 2; // 只要通知就是成功,不成功的不通知
- $o->uid = $args['guid'];
- $o->amount = $args['pay_price'] * 100; // float 单位:元, Ps.游戏后台是分
- // $o->callbackInfo = $args['cpprivate'];
- // $o->otherInfo = 'transtype:' . $args['transtype']; // 交易类型
- return $o;
- }
- // </editor-fold>
- //
- }
|