notifyData = input(); if (!$this->notifyData) { $this->notifyData = request()->getInput(); } log_message('REQ.rawInput:'. json_encode($this->notifyData), 'log', LOG_PATH . 'PayNotify/'); } catch (\Exception $e) { exit("fail: 处理异常!"); } } /** * 支付宝服务器异步通知页面方法 */ public function alipay() { vendor('alipay.lib.AlipayNotify'); $alipayNotify = new \AlipayNotify(Config::get('alipay')); $result = $alipayNotify->verifyNotify(); $out_trade_no = input('out_trade_no'); //订单号 //写入日志 log_message("## alipay: ". $out_trade_no.' - '.($result?"success":"fail"), 'log', LOG_PATH . '../paylog/'); if ($result) { // 处理支付成功后的逻辑业务 if (input('post.trade_status') == 'TRADE_SUCCESS') { if (!empty($out_trade_no)) { //更新订单状态处理 $this->updateOrder($out_trade_no, input('total_fee')); } echo 'success'; exit; //请不要修改或删除 } echo 'fail'; exit; //验证失败 } echo 'fail'; exit; } /** * 支付宝Aop支付服务器异步通知页面方法 */ public function alipayAop() { //Alipay Aop Sdk支付回调 vendor('alipayAop.AopSdk'); $app_id = input('app_id'); $out_trade_no = input('out_trade_no', ''); //订单号 $configs = Config::get('ali_pay_config'); $configs_list = array_keys($configs['configs']); if(!in_array($app_id, $configs_list)){ ddMsg('warning', '', ['PayNotify.alipayAop.fail', '回调时 appId 配置不存在!', $app_id.'-'.$out_trade_no]); echo "fail"; exit; //验证失败 } $aop = new \AopClient(); $aop->alipayrsaPublicKey = $configs['configs'][$app_id]['public_key']; $result = $aop->rsaCheckV1(input(), NULL, $configs['sign_type']); if ($result) { // 处理支付成功后的逻辑业务 // 交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款) if (in_array(input('post.trade_status'), ['TRADE_SUCCESS', 'TRADE_CLOSED'])) { //写入日志 // log_message("## alipayAop: ". $out_trade_no .' - '. $result, 'log', LOG_PATH . '../paylog/'); if (!empty($out_trade_no)) { // total_amount=订单金额, refund_fee=退款金额 //更新订单状态处理 $this->updateOrder($out_trade_no, input('total_amount'), 'ali_pay'); } echo 'success'; exit; //请不要修改或删除 } echo 'fail'; exit; //验证失败 } ddMsg('weelfar', '', ['PayNotify.alipayAop.fail', '回调失败!', $app_id.'-'.$out_trade_no]); echo 'fail'; exit; } /** * 威富通-微信 支付完成回调处理 * */ public function swiftpay() { vendor('swiftpay.ClientResponseHandler', '.class.php'); $resHandler = new \ClientResponseHandler(); //后台应答类 $xml = file_get_contents('php://input'); //写入日志 log_message($xml, 'log', LOG_PATH . '../paylog/'); $resHandler->setContent($xml); $resHandler->setKey(Config::get('swiftpay')['key']); //签名验证 if ($resHandler->isTenpaySign()) { if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0) { //支付成功时 if ($resHandler->getParameter('pay_result') == 0) { $orderid = $resHandler->getParameter('out_trade_no'); $total_fee = $resHandler->getParameter('total_fee') / 100; //金额,分为单位 //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $total_fee); } } else { //写入日志 log_message('支付失败', 'error', LOG_PATH . '../paylog/'); } echo 'success'; exit(); } else { echo 'failure1'; exit(); } } else { //写入日志 log_message('威富通-微信 支付签名验证失败', 'error', LOG_PATH . '../paylog/'); echo 'failure2'; exit(); } exit(); } /** * 威富通中信银行-微信WAP支付回调处理 * */ public function swiftccbwxpay() { vendor('swiftpay.ClientResponseHandler', '.class.php'); $resHandler = new \ClientResponseHandler(); //后台应答类 $xml = file_get_contents('php://input'); //写入日志 log_message($xml, 'log', LOG_PATH . '../paylog/'); $resHandler->setContent($xml); $resHandler->setRSAKey(Config::get('swiftccbwxpay')['public_key']); $resHandler->setParameter('sign_type', 'RSA_1_256'); //签名验证 if ($resHandler->isTenpaySign()) { if ($resHandler->getParameter('status') == 0 && $resHandler->getParameter('result_code') == 0) { //支付成功时 if ($resHandler->getParameter('pay_result') == 0) { $orderid = $resHandler->getParameter('out_trade_no'); $total_fee = $resHandler->getParameter('total_fee') / 100; //金额,分为单位 //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $total_fee); } } else { //写入日志 log_message('支付失败', 'error', LOG_PATH . '../paylog/'); } echo 'success'; exit(); } else { echo 'failure1'; exit(); } } else { //写入日志 log_message('威富通-微信 支付签名验证失败', 'error', LOG_PATH . '../paylog/'); echo 'failure2'; exit(); } exit(); } /** * 第三方 现在支付完成回调处理 * */ public function zfbxjzfipaynow() { //返回的参数 $res = file_get_contents('php://input'); //写入日志 log_message('现在支付回调参数:' . $res, 'log', LOG_PATH . '../paylog/'); $Arr = array(); $res = explode('&', $res); //写入日志 log_message('现在支付explode处理后的回调参数:' . print_r($res, true), 'log', LOG_PATH . '../paylog/'); foreach ($res as $v) { $value = explode('=', $v); $Arr[$value[0]] = urldecode($value[1]); } $signatrue = $this->getIpaynowSignTrue($Arr, Config::get('h5_alipay_config')['key']); if ($signatrue == $Arr['signature']) { $orderid = $Arr['mhtOrderNo']; $mhtOrderAmt = $Arr['mhtOrderAmt'] / 100; //商户订单交易金额,以分为单位 //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $mhtOrderAmt); } //异步通知验签通过,在此处写业务逻辑 echo 'success=Y'; } else { //写入日志 log_message('现在支付签名验证失败', 'error', LOG_PATH . '../paylog/'); //异步通知验签失败,在此处写业务逻辑 echo 'success=N'; } } /** * 现在支付完成回调处理 * */ public function ipaynow() { //返回的参数 $res = file_get_contents('php://input'); //写入日志 log_message('现在支付回调参数:' . $res, 'log', LOG_PATH . '../paylog/'); $Arr = array(); $res = explode('&', $res); //写入日志 log_message('现在支付explode处理后的回调参数:' . print_r($res, true), 'log', LOG_PATH . '../paylog/'); foreach ($res as $v) { $value = explode('=', $v); $Arr[$value[0]] = urldecode($value[1]); } $signatrue = $this->getIpaynowSignTrue($Arr, Config::get('h5_alipay_config')['key']); if ($signatrue == $Arr['signature'] && $Arr['transStatus'] == 'A001') { $orderid = $Arr['mhtOrderNo']; $mhtOrderAmt = $Arr['mhtOrderAmt'] / 100; //商户订单交易金额,以分为单位 //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $mhtOrderAmt); } //异步通知验签通过,在此处写业务逻辑 echo 'success=Y'; } else { //写入日志 log_message('现在支付签名验证失败', 'error', LOG_PATH . '../paylog/'); //异步通知验签失败,在此处写业务逻辑 echo 'success=N'; } } /** * 对现在支付回调的请求报文做签名验证, * copy现在支付demo代码中controller.php的getSignTrue方法 * * @param $Arr array 报文参数 * @param $key string * * @return mix */ private function getIpaynowSignTrue($Arr, $key) { if (!empty($Arr)) { ksort($Arr); $str = ''; foreach ($Arr as $k => $v) { if ($v == '' || $k == 'signature') { continue; } $str .= $k . '=' . $v . '&'; } if ($key == 'post') { return substr($str, 0, -1); } else { return strtolower(md5($str . md5($key))); } } return false; } /** * 微信官方h5支付 */ public function wxpayh5() { $request_data = file_get_contents('php://input'); //写入日志 log_message('微信h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); $wxPay = new WeixinPay; $data = $wxPay->xmlToArray($request_data); $data = array_filter($data); $source_sign = $data['sign']; // 接收到的签名 unset($data['sign']); // 参数中的sign不参与签名 //生成的签名 $sign = $wxPay->MakeSign($data, Config::get('wxpay-h5')['key']); //验签失败 if ($source_sign !== $sign) { $return['return_code'] = 'failure'; $return['return_msg'] = 'NO'; //写入日志 log_message('微信官方h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); } elseif ('SUCCESS' != $data['result_code']) { $return['return_code'] = 'failure'; $return['return_msg'] = 'NO'; //写入日志 log_message('微信官方h5支付错误代码:' . $data['err_code'] . '; 错误信息: ' . $data['err_code_des'], 'error', LOG_PATH . '../paylog/'); } else { $orderid = $data['out_trade_no']; $amount = $data['total_fee'] / 100; //商户订单交易金额,以分为单位 //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } $return['return_code'] = 'SUCCESS'; $return['return_msg'] = 'OK'; } echo dataToXml($return); exit; } /** * 米花微信h5支付 */ public function wxpayh5mihua() { $request_data = file_get_contents('php://input'); //写入日志 log_message('米花微信h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('mihuaSdk.Mihua', '.class.php'); $mihua = new \Mihua(); $data = $_GET['data']; $retjson = $mihua->notifyVerify($data); if ($retjson && $retjson['orderStatus'] == 'SUCCESS') { $orderid = $retjson['orderId']; $amount = floatval($retjson['amount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "SUCCESS"; die(); } else { log_message('米花微信h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); echo 'FAIL'; exit(); } } /** * 米花支付宝h5支付 */ public function zfbh5mihua() { $request_data = file_get_contents('php://input'); //写入日志 log_message('米花支付宝h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('mihuaSdk.Mihuazfb', '.class.php'); $mihua = new \Mihuazfb(); $data = $_GET['data']; $retjson = $mihua->notifyVerify($data); if ($retjson && $retjson['orderStatus'] == 'SUCCESS') { $orderid = $retjson['orderId']; $amount = floatval($retjson['amount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "SUCCESS"; die(); } else { log_message('米花支付宝h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); echo 'FAIL'; exit(); } } /** * 快接微信h5支付 */ public function wxpayh5kj() { $request_data = file_get_contents('php://input'); //写入日志 log_message('快接微信h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('kjpaySdk.Kjpay', '.class.php'); $kjpay = new \Kjpay(); $data = $_POST; $retjson = $kjpay->notifyVerify($data); if ($retjson && $retjson['status'] == 'Success') { $orderid = $retjson['merchant_order_no']; $amount = floatval($retjson['amount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "success"; die(); } else { log_message('快接微信h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); echo 'fail'; exit(); } } /** * 快接支付宝h5支付 */ public function zfbh5kj() { $request_data = file_get_contents('php://input'); //写入日志 log_message('快接支付宝h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('kjpaySdk.Kjzfb', '.class.php'); $kjpay = new \Kjzfb(); $data = $_POST; $retjson = $kjpay->notifyVerify($data); if ($retjson && $retjson['status'] == 'Success') { $orderid = $retjson['merchant_order_no']; $amount = floatval($retjson['amount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "success"; die(); } else { log_message('快接支付宝h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); echo 'fail'; exit(); } } /** * 商盟微信h5支付 */ public function wxpayh5sumpay() { $request_data = file_get_contents('php://input'); //写入日志 log_message('商盟微信h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('sumpaySdk.Sumpay', '.class.php'); $sumpay = new \Sumpay(); $retData = array(); $data = $_REQUEST; $retjson = $sumpay->notifyVerify($data); if ($retjson && $retjson['status'] == '1') { $orderid = trim($retjson['orderNo']); $amount = floatval($retjson['orderAmount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } $retData['code'] = '10000'; echo json_encode($retData); exit(); } else { log_message('商盟微信h5支付签名验证失败:' . print_r($data, true), 'error', LOG_PATH . '../paylog/'); $retData['code'] = '30000'; echo json_encode($retData); exit(); } } /** * 酷点h5支付 */ public function kdh5zhifu() { $request_data = file_get_contents('php://input'); log_message('酷点h5支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); vendor('kdpaySdk.des'); $sumpay = new \kdpay(); $data = json_decode($request_data, true); $res_result = json_decode($data['result'], true); if ($res_result['status'] == '100') { $retjson = $sumpay->notifyVerify($data); if ($retjson == $data['sign']) { $orderid = trim($res_result['out_trade_no']); $amount = floatval($res_result['fee'] / 100); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "success"; die(); } else { echo 'fail'; exit(); } } else { echo '支付失败'; exit(); } } /** * 汇付宝 微信H5支付回调 */ public function wxwapnotify() { //$param = request()->param(); //写入日志 //log_message('回调参数'.json_encode($param),'error',LOG_PATH . '../paylog/'); $sign_key = Config::get('wxwappay-h5')['key']; $result = $_GET['result']; $pay_message = $_GET['pay_message']; $agent_id = $_GET['agent_id']; $jnet_bill_no = $_GET['jnet_bill_no']; $agent_bill_id = $_GET['agent_bill_id']; $pay_type = $_GET['pay_type']; $pay_amt = $_GET['pay_amt']; $remark = ""; $return_sign = $_GET['sign']; $signStr = ''; $signStr = $signStr . 'result=' . $result; $signStr = $signStr . '&agent_id=' . $agent_id; $signStr = $signStr . '&jnet_bill_no=' . $jnet_bill_no; $signStr = $signStr . '&agent_bill_id=' . $agent_bill_id; $signStr = $signStr . '&pay_type=' . $pay_type; $signStr = $signStr . '&pay_amt=' . $pay_amt; $signStr = $signStr . '&remark=' . $remark; $signStr = $signStr . '&key=' . $sign_key; //商户签名密钥 $sign = ''; $sign = md5($signStr); if ($sign == $return_sign) { //比较签名密钥结果是否一致,一致则保证了数据的一致性 //订单编号不为空时 if (!empty($agent_bill_id)) { //更新订单状态处理 $this->updateOrder($agent_bill_id, $pay_amt); } echo "success"; die(); } else { echo 'fail'; exit(); } } /** * 汇付宝 微信H5支付回调 */ public function wxwapreturn() { echo 'fail'; exit(); } /** * TODO: 全民付 支付回调 */ public function qmf_pay() { /** * msgType=wx.orderQuery &payTime=2022-06-21 17:29:25 &connectSys=OPENCHANNEL &sign=A188B6B03255E111F19A73D17CFC44ABEED713D88B5BE965D05028E0B3129CF6 &merName=中保付测试商户(中保付测试商户) &mid=898201612345678 &invoic eAmount=1 &settleDate=2022-06-21 &billFunds=现金支付0.01元。 &buyerId=o8wNP0Rl-a0Xz0FPKsxgSHEv2jYs &mchntUuid=6d47dc12a4c847eaba2eb456d201d5cd &tid=88880001 &instMid=QRPAYDEF AULT &receiptAmount=1 &targetOrderId=4200001498202206214650782137 &signType=SHA256 &orderDesc=全攻坚补款 &seqId=01120706254N &merOrderId=319420220 621172858801SF554320 &targetSys=WXPay &totalAmount=1 &createTime=2022-06-21 17:29:13 &buyerPayAmount=1 ¬ifyId=32ae8766-bbbe-4c40-a1bd-7c082ffe668b &HC=ogHg &subInst=100200 &status=TRADE_SUCCESS */ $request_data = file_get_contents('php://input'); log_message('全民付 支付回调参数:' . $request_data, 'log', LOG_PATH . '../paylog/'); $data = json_decode($request_data, true); if ($data['status'] == 'TRADE_SUCCESS') { $sign = $this->notifyVerify($data, 'xxxx'); if ($sign == $data['sign']) { $orderid = trim($data['merOrderId']); $amount = floatval($data['totalAmount'] * 100); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } echo "SUCCESS"; exit(); } else { echo 'FAILED'; exit(); } } else { echo 'FAILED'; exit(); } } public function notifyVerify($data, $appkey){ unset($data['sign']); $Parameters = []; foreach ($data as $k => $v) { if($v && $v != ""){ $Parameters[$k] = $v; } } //签名步骤一:按字典序排序参数 ksort($Parameters); $buff = ""; foreach ($Parameters as $k => $v) { $buff .= $k . "=" . $v . "&"; } $String = $buff . $appkey; //签名步骤三:MD5加密 // $sign = md5($String); $sign = hash('sha256', $String); return $sign; } // 易宝支付 - 支付回调 public function ybzf_pay(){ // 文档: https://www.eolink.com/share/inside/f8LYBC/api/2161864/detail/48968582 $postData = input(); if($postData['returncode'] != '0000'){ ddMsg('warning', '', ['PayNotify.ybzf_pay.fail', '失败订单回调!', $postData['paytype'].'-'.$postData['orderno']]); echo "fail"; exit(); } $private_key = Config::get('ybzf_pay')['private_key']; // 签名要求: MD5(paytime=xxx|orderno=xxxxx|payno=xxxx|paytype=xxx|productprice=xxxx|商户密钥) $signData = [ 'paytime' => $postData['paytime'], // 支付时间 例:202209181022 'orderno' => $postData['orderno'], // 订单号 'payno' => $postData['payno'], // 系统号 'paytype' => $postData['paytype'], // 支付类型: 1=支付宝、2=微信、3=联快捷、4=程序、5=务窗、6=APP、7=钱包 'productprice' => $postData['productprice'], // 商品价格(单位:分) ]; $signHandle = ''; foreach ($signData as $k=>$v) { if($signHandle){ $signHandle .= '|'; } $signHandle .= $k.'='.$v; } $sign = md5($signHandle.'|'.$private_key); $result = $postData['sign'] == $sign; //写入日志 log_message("## ybzf_pay: ". $signData['orderno'].' - sign: '.$postData['sign'] .' - '. $sign.' - res:'.($result?"success":"fail"), 'log', LOG_PATH . '../paylog/'); if($result){ if (!empty($signData['orderno'])) { // 更新订单状态处理 $this->updateOrder($signData['orderno'], formatFenToYuan($postData['productprice'])); } echo "success"; exit(); } ddMsg('weelfar', '', ['PayNotify.ybzf_pay.fail', '回调失败!', $postData['paytype'] . '-' . $postData['orderno']]); echo "fail"; exit(); } // 联动优势-微信小程序 - 支付回调 public function ldzf_wx_pay() { $input = input(); if (!$input) { $input = request()->getInput(); } $result = NotifPay::makeNotify('ldys_pay', $input); if ($result['error'] == false) { if ($this->updateOrder($input['order_id'], formatFenToYuan($input['amount'])) == true) { echo NotifPay::makeReturnNotify("ldys_pay", $result['result']); exit(); } } echo NotifPay::makeReturnNotify('ldys_pay', 'fail'); exit(); } // 趣智连支付 - 支付回调 public function qzl_pay() { // 【参数内容重置获取】获取原始请求体,保留 + 号(PHP 的 $_POST/parse_str 会把 + 转成空格) $this->notifyData = file_get_contents('php://input'); $this->notifyData = parseParamsKeepPlus($this->notifyData); if (!$this->notifyData) { $this->notifyData = input(); } $input = $this->notifyData; // dump($this->notifyData); $notifyResult = NotifPay::makeNotify('qzl_pay', $input); $result = $notifyResult['result']; if ($notifyResult['result'] == "success") { if ($this->updateOrder($input['mchOrderNo'], formatFenToYuan($input['amount']), 'qzl_pay') == false) { $result = 'fail:订单号不存在或金额有误!'; if($this->payErrMsg){ $result = $this->payErrMsg; } } } echo $result; if($result != "success"){ trace('PayNotify.qzl_pay.err.result: ' . $result, 'log'); } exit(); } // 优亿支付 - 支付回调 public function yyyb_pay() { $input = input(); if (!$input) { $input = request()->getInput(); } $result = NotifPay::makeNotify('yyyb_pay', $input); if ($result['result'] == "success") { if ($this->updateOrder($input['mchOrderNo'], formatFenToYuan($input['amount'])) == false) { $result['result'] = NotifPay::makeReturnNotify('qzl_pay', 'fail'); } } echo $result['result']; exit(); } // 喜钛游 public function xty_pay() { $input = $this->notifyData; try { if(is_json($input)){ $input = json_decode($input, true); } $notifyResult = NotifPay::makeNotify('xty_pay', $input); $result = $notifyResult['result']; if ($notifyResult['result'] == "success") { $signData = json_decode($input["req_data"], true); if ($this->updateOrder($signData['out_trade_no'], formatFenToYuan($signData['total_amount']), 'xty_pay') == false) { $result = 'fail:订单号不存在或金额有误!'; } if($this->payErrMsg){ $result = 'fail:'.$this->payErrMsg; } } } catch (\Exception $e) { $result = "fail:支付回调异常:" . $e->getMessage(); } echo $result; if($result != "success"){ trace('PayNotify.yyyb_pay.err.result: ' . $result, 'log'); } exit(); } public function pay_refund(){ die('xxx'); $orderid = makeOrderid('TK_'); // $input = input(); // $payInfo = Db::table('cy_pay')->field('id,orderid,status,amount,real_amount,userid,gameid,channel_id,ip,coupon_member_id,coupon_amount,real_coin,coupon_member_id')->where(['orderid' => $input['orderid']])->find(); // $refundData = [ // "out_trade_no" => $payInfo['orderid'], // 商户订单号 // // "order_no" => $order_no, // 交易流水号 // "out_refund_no" => $orderid, // 商户退款单号 // "refund_amount" => formatYuanToFen($payInfo['real_amount']), // 退款金额(分) // "refund_reason" => "订单已取消,系统退款处理", // 退款原因 // ]; $refundData = [ "out_trade_no" => "WL17739740192510156790", // 商户订单号 "out_refund_no" => $orderid, // 交易流水号 // "refund_amount" => 0.01, // 退款金额(元) "refund_amount" => formatYuanToFen(0.01), // 退款金额(分) "refund_reason" => "订单已取消,系统退款处理", // 退款原因 ]; //订单使用了代金卷或平台币,则进行退款处理 // $refundRsult = \app\common\factory\Pay::makeRefund('ali_pay', $refundData); $refundRsult = \app\common\factory\Pay::makeRefund('xty_pay', $refundData); dump($refundRsult); } /** * 更新订单信息 * * @param string $orderid :订单编号 * @param string $real_amount :第三方支付的金额(现金部分)(单位:元:6.48) * @param string $paytype :支付类型 * * @return boolean */ private function updateOrder($orderid, $real_amount = '', $paytype = '') { $payModel = new Pay; $payCpinfoModel = new PayCpinfo; $membersModel = new Members; $result = false; // ## 订单信息 $payInfo = $payModel->field('id,status,amount,real_amount,userid,gameid,channel_id,ip,coupon_member_id,coupon_amount,real_coin,coupon_member_id')->where(['orderid' => $orderid])->find(); // dump($payInfo); if(!$payInfo){ return "当前订单不存在!"; } if ($payInfo['status'] == 1 && $payInfo['real_amount'] == $real_amount) { return true; } // TODO: 缺少订单如果成功后,又取消的订单回调时,处理订单状态由已成功改为已取消;(需要查第三方订单状态确实) /** * ## 订单已取消处理 * - 第三方返回支付成功,检测订单状态为已取消时,检测此订单是否包含平台币/代金券,包含任意其中一个则自动退款,不包含则订单成功; */ if(in_array($payInfo['status'], [2, 3]) && $paytype){ // 如果交易包含 平台币或代金券,则进行退款处理 if($payInfo['real_amount'] > 0 || $payInfo['real_coin'] > 0 || $payInfo['coupon_amount'] > 0){ trace("0. 退款中 - Loading: orderid={$orderid}, refund_amount={$payInfo['real_amount']}", 'log'); // $refundOrderId = makeOrderid('REF'); $refundData = [ "out_trade_no" => $orderid, // 商户订单号(祈盟) // "order_no" => $order_no, // 交易流水号(商户平台) "out_refund_no" => $orderid.'_T', // 商户退款单号 "refund_amount" => $payInfo['real_amount'], // 退款金额(元) "refund_reason" => "订单已取消,系统自动退款处理", // 退款原因 ]; $refundRsult = \app\common\factory\Pay::makeRefund($paytype, $refundData); // 退款 - 已处理过 if($refundRsult['code'] == 210){ return true; } // 退款 - 处理成功 if($refundRsult['code'] != 200){ $this->payErrMsg = $refundRsult['msg']; trace("-1. 退款失败 - FAIL: orderid={$orderid}, msg=". $refundRsult['msg'], 'log'); return false; } trace("1. 退款成功 - SUCCESS: orderid={$orderid}, msg=". $refundRsult['msg'], 'log'); $payModel->where(['id' => $payInfo['id']])->update(['status' => 2, 'beizhu' => '订单已取消,系统自动退款处理']); // 更新订单状态为 超时取消 return true; } } // ## 支付成功,通知CP if ($payInfo['status'] == 1) { (new PayCallback())->callBackToCp($orderid); // 代金卷使用成功通知 if (!empty($payInfo['coupon_member_id'])) { (new \app\api\controller\YqlData())->notifyCoupon($payInfo['coupon_member_id']); } return true; } if ($real_amount != '' && strval($payInfo['real_amount']) != $real_amount) { $result = false; //写入日志 log_message('订单编号:' . $orderid . '支付金额不一致,订单状态更新失败', 'error', RUNTIME_PATH . 'paylog/'); } // 待支付状态时 elseif ($payInfo['status'] == 0 || $payInfo['status'] == 2) { // 启动事务 Db::startTrans(); try { cache('PayNotify:updateOrder:' . $orderid, $payInfo, 300); $payModel->where(['id' => $payInfo['id']])->update(['status' => 1, 'pay_time' => NOW_TIMESTAMP]); //cy_paycpinfo表记录状态更新 $payCpinfoModel->where(['orderid' => $orderid])->update(['payflag' => 1]); //增加用户积分 $this->memberjifen($payInfo['userid'], $payInfo['gameid'], $payInfo['real_amount']); //代金券处理 if($payInfo['coupon_member_id']>0 && $payInfo['coupon_amount']>0){ model('common/CouponMember')->updateCouponIsUseById($payInfo['coupon_member_id'],3); } $result = true; // 提交事务 Db::commit(); // log_message('TiktokService:push:'.$orderid, 'info', LOG_PATH . '../tiktok/'); //2022-10-13 抖音推送 // $extend = [ // 'Oaid' => '', // 'Idfa' => '', // 'Androidid' => '', // 'Imei' => '', // 'PayAmount' => $payInfo['amount'], // 'Ip' => $payInfo['ip'] // ]; // $tiktokService = new TiktokService(); // $tiktokService->push('tiktok.active_pay', $payInfo['userid'], $payInfo['gameid'], $payInfo['channel_id'], $extend); } catch (\Exception $e) { // 回滚事务 Db::rollback(); $result = false; //写入日志 log_message('订单编号:' . $orderid . '订单状态更新失败' . $e->getMessage(), 'error', RUNTIME_PATH . 'paylog/'); } } //订单状态更新成功 if ($result) { //更新member表的total_pay_amount $membersModel->where(['id' => $payInfo['userid']])->update(['total_pay_amount' => Db::raw('total_pay_amount+' . $payInfo['amount'])]); // 通知CP,支付成功 (new PayCallback())->callBackToCp($orderid); //预警邮件 (new PayLogic())->payWarning($payInfo['userid'], $payInfo['channel_id'], $payInfo['gameid'], $payInfo['amount']); // 代金卷使用成功通知 if (!empty($payInfo['coupon_member_id'])) { (new YqlData())->notifyCoupon($payInfo['coupon_member_id']); } } return $result; } /** * 用户玩家积分 */ private function memberjifen($userid, $gameid, $amount) { $jifen_ratio = Db::name("cy_game")->where(['id' => $gameid])->value('jifen_ratio'); if (!empty($jifen_ratio)) { $jifen = $amount * $jifen_ratio; } else { $jifen_ratio = 1; $jifen = $amount * $jifen_ratio; } $jifen_info['game_id'] = $gameid; $jifen_info['user_id'] = $userid; $jifen_info['amount'] = $amount; $jifen_info['type'] = 1; $jifen_info['jifen_ratio'] = $jifen_ratio; $jifen_info['jifen'] = $jifen; $jifen_info['create_time'] = time(); Db::name("cy_member_jifen_record")->insert($jifen_info); Db::name("cy_members")->where(['id' => $userid])->update(['jifen' => Db::raw('jifen+' . $jifen)]); } public function airwallex() { $postData = request()->getInput(); $header = [ 'timestamp' => request()->header('x-timestamp') ?: time(), 'signature' => request()->header('x-signature') ?: '', ]; log_message('header:' . json_encode(request()->header()) . ' data:' . $postData, 'log', LOG_PATH . 'PayNotify/airwallex/'); $airwallexPay = new AirwallexPay(); if ($airwallexPay->notify($postData, $header)) { $data = json_decode($postData, true); if (substr($data['data']['object']['merchant_order_id'], 0, 4) == 'COIN') { $orderid = $data['data']['object']['merchant_order_id']; $amount = floatval($data['data']['object']['amount']); $callback_order = $data['sourceId']; $currency = $data['data']['object']['currency']; //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 (new PayNotifyService())->updateOrderCoin($orderid, $amount, $callback_order, $currency); } } else { $orderid = $data['data']['object']['merchant_order_id']; $amount = floatval($data['data']['object']['amount']); //订单编号不为空时 if (!empty($orderid)) { //更新订单状态处理 $this->updateOrder($orderid, $amount); } } echo 'ok'; exit(); } else { throw new \Exception('signature invalid'); } } // 电魂支付回调 public function dianhun(){ // 获取请求参数 - 根据注释中的参数列表 $input = \think\Request::instance()->only([ 'qm_username', // 祈盟用户名 'qm_game_id', // 祈盟game_id 'order_id', // 游戏方订单号 'amount', // 金额(单位/元) 'product_name', // 商品名 'product_desc', // 商品介绍 'pay_type', // 支付方式(dh_zfb=支付宝/dh_wx=微信) 'create_time', // 下单时间 'pay_time', // 支付时间 'sign' // sign ], 'post'); // 参数验证规则 $validate = new Validate([ 'qm_username' => 'require', 'qm_game_id' => 'require', 'order_id' => 'require', 'amount' => 'require', 'product_name' => 'require', 'pay_type' => 'require', 'create_time' => 'require', 'pay_time' => 'require', 'sign' => 'require', ]); // 验证参数 if (!$validate->check($input)) { return '{"code": -110, "msg": "请求参数有误:'.$validate->getError().'"}'; } try { // 签名 $app_key = model('App')->where(['gameid' => $input['qm_game_id']])->value('appkey'); if(!$app_key){ return '{"code": -110, "msg": "当前游戏数据异常!"}'; } ksort($input); $str = ''; foreach($input as $k => $v){ if($k == 'sign'){ continue; // 跳过签名字段 } if($str){ $str .= '&' . $k . '=' . $v; }else{ $str .= $k . '=' . $v; } } $sign = md5($str.$app_key); if($sign != $input['sign']){ return '{"code": -110, "msg": "签名异常!"}'; } $userInfo = Db::table('nw_subaccount')->alias('ns') ->join('cy_members cm', 'ns.member_id = cm.id', 'left') ->join('nw_member_game_server nmgs', 'ns.member_id = nmgs.member_id AND nmgs.game_id=ns.game_id AND nmgs.channel_id=ns.channel_id', 'left') ->field("ns.member_id,ns.game_id,ns.channel_id,cm.username, nmgs.ip,nmgs.imeil,nmgs.roleid,nmgs.rolename,nmgs.rolelevel,nmgs.serverid,nmgs.servername") ->where(['ns.sub_username' => $input['qm_username'], 'ns.game_id' => $input['qm_game_id']]) ->find(); if(!$userInfo){ return '{"code": -110, "msg": "当前账户数据异常!"}'; } // 判断订单是否存在 if(Db::table('cy_pay')->where(['attach' => $input['order_id'], 'gameid' => $input['qm_game_id']])->count() > 0){ return '{"code": 200, "msg": "success."}'; } $orderData = [ 'orderid' => makeOrderid(), 'userid' => $userInfo['member_id'], 'username' => $userInfo['username'], 'channel_id' => $userInfo['channel_id'], 'gameid' => $input['qm_game_id'], 'status' => 1, 'paytype' => $input['pay_type'], 'amount' => $input['amount'], // 订单金额 'real_amount' => $input['amount'], // 支付金额 // 角色信息 'roleid' => $userInfo['roleid'], 'rolename' => $userInfo['rolename'], 'rolelevel' => $userInfo['rolelevel'], 'productname' => $input['product_name'], 'productdesc' => $input['product_desc'], 'serverid' => $userInfo['serverid'], 'servername' => $userInfo['servername'], 'ip' => $userInfo['ip'], 'imeil' => $userInfo['imeil'], // 'create_time' => $input['create_time'], // 'pay_time' => $input['pay_time'], // 修改电魂订单的下单时间和支付时间逻辑(为了祈盟平台抓取数据方便,这里做修改); 'create_time' => $input['pay_time'], 'pay_time' => time(), 'beizhu' => '电魂订单', // 备注 'attach' => $input['order_id'], // CP扩展参数 'discount' => 1, // 折扣比例 'pay_amount' => $input['amount'], // 支付金额 ]; $result = Db::table('cy_pay')->insert($orderData); if(!$result){ return '{"code": -130, "msg": "订单记录失败"}'; } $cpInfo = [ 'orderid' => $orderData['orderid'], 'appid' => 0, 'status' => 1, 'payflag' => 1, 'create_time' => $input['create_time'], 'update_time' => $input['pay_time'], ]; $result = Db::table('cy_paycpinfo')->insert($cpInfo); if(!$result){ return '{"code": -131, "msg": "订单详情记录失败"}'; } return '{"code": 200, "msg": "success"}'; } catch (\Exception $e) { $result = '{"code": -150, "msg": "请求参数异常:'.$e->getMessage().'"}'; log_message('订单存储失败:'. json_encode(input()).' - result: '.$result, 'log', LOG_PATH . 'PayNotifyDianHun/'); curlDD("电魂订单异常: input=" . json_encode(input()).' - error='. $result, Env::get('dingtalk.notic_url')); return $result; } return '{"code": -120, "msg": "订单记录失败"}'; } }