0, 'msg' => '操作有误'); } if (is_array($pay_order)) { $PayOrderModel = D('RetailPayOrder'); $pay_order_id = $pay_order[$PayOrderModel::ID]; } else { $pay_order_id = $pay_order; } $GCRModel = D('RetailGiftCardRecord'); $gift_order = $GCRModel->getFind(array($GCRModel::PAY_ORDER_ID => $pay_order_id)); if (!empty($gift_order)) { $update = $GCRModel->updateOrder(array($GCRModel::ID => $gift_order[$GCRModel::ID]), array($GCRModel::STATE => 1)); $GCPModel = D('RetailGiftCardPrice'); $update1 = $GCPModel->toSetDec(array($GCPModel::ID => $gift_order[$GCRModel::GIFT_PRICE_ID]), $GCPModel::LESS_NUM, 1); $res['status'] = 1; $res['msg'] = '购买成功'; } else { $res['status'] = 0; $res['msg'] = '订单不存在'; } return $res; } /** * 小程序订单退款 ** @param $billOrder 新退款记录(bill_order表数据) * @param $old_bill_order 原购买订单 * @param int $cashier_id 收银员id * @return array */ public function onlineRefund_v1($billOrder, $old_bill_order, $cashier_id = 0) { if (!$billOrder || !is_array($billOrder)) { $result['status'] = 0; $result['msg'] = '缺少参数'; return $result; } $BillModel = D('RetailBillOrder'); $merchant_id = $old_bill_order[$BillModel::MERCHANT_ID]; $refundOrder = D('RefundOrder')->getFindOrderAsc($merchant_id);//退款顺序 $lessRefundMoney = $billOrder[$BillModel::ALL_MONEY];//存储剩余退款的金额 $PayOrderModel = D('RetailPayOrder'); $pMap = array( $PayOrderModel::BILL_ID => $old_bill_order[$BillModel::ID], $PayOrderModel::ORDER_TYPE => 1, $PayOrderModel::ORDER_STATE => 'SUCCESS', ); $balance = 0; $Wx = 0; foreach ($refundOrder as $key => $value) { if ($key == 'vip_refund_order') { $pMap[$PayOrderModel::PAY_TYPE] = 6; $bPayOrder = $PayOrderModel->getFind($pMap); if (!empty($bPayOrder)) { $lessMoney = round($bPayOrder[$PayOrderModel::TRADE_AMOUNT] - $bPayOrder[$PayOrderModel::REFUND_MONEY], 2);//剩余可用来退款的金额 if ($lessMoney > 0) { if ($lessMoney > $lessRefundMoney) { $balance = $lessRefundMoney; } else { $balance = $lessMoney; } $lessRefundMoney = round($lessRefundMoney - $balance, 2); } } } else if ($key == 'wx_refund_order') { $pMap[$PayOrderModel::PAY_TYPE] = 4; $wxPayOrder = $PayOrderModel->getFind($pMap); if (!empty($wxPayOrder)) { if ($wxPayOrder['pay_coupon_fee'] > 0) { //微信支付 $wxPayOrder[$PayOrderModel::TRADE_AMOUNT] = bcadd($wxPayOrder[$PayOrderModel::TRADE_AMOUNT], $wxPayOrder['pay_coupon_fee'], 2); $wxPayOrder[$PayOrderModel::REFUND_MONEY] = bcadd($wxPayOrder[$PayOrderModel::REFUND_MONEY], $wxPayOrder['refund_coupon_fee'], 2); } file_put_contents('./all4.txt', json_encode($wxPayOrder) . PHP_EOL, FILE_APPEND); $lessMoney = round($wxPayOrder[$PayOrderModel::TRADE_AMOUNT] - $wxPayOrder[$PayOrderModel::REFUND_MONEY], 2);//剩余可用来退款的金额 if ($lessMoney > 0) { if ($lessMoney > $lessRefundMoney) { $Wx = $lessRefundMoney; } else { $Wx = $lessMoney; } $lessRefundMoney = round($lessRefundMoney - $Wx, 2); } } } if ($lessRefundMoney == 0) { break; } } if ($Wx > 0 || $balance > 0) { $item = array( $PayOrderModel::SCENE_TYPE => 2, //'1付款 2退款', $PayOrderModel::ORDER_TYPE => 1, //'1购买商品', $PayOrderModel::STORE_ID => $billOrder[$BillModel::STORE_ID], //'门店id', $PayOrderModel::MERCHANT_ID => $billOrder[$BillModel::MERCHANT_ID], //'商户id', $PayOrderModel::CASHIER_ID => $cashier_id, //'收银员id', $PayOrderModel::ADD_TIME => time(), //'订单创建时间', $PayOrderModel::BILL_ID => $billOrder[$BillModel::ID], //'bill表id', $PayOrderModel::VID => $billOrder[$BillModel::VID], //'会员id', $PayOrderModel::UID => $billOrder[$BillModel::UID], //'小程序用户id', $PayOrderModel::ORDER_STATE => 'WAIT_REFUND', ); } if (!empty($wxPayOrder) && $Wx > 0) { //微信退款 $pay_type = 6; $item[$PayOrderModel::PAY_ORDER_ID] = $wxPayOrder[$PayOrderModel::ID]; $item[$PayOrderModel::PAY_TYPE] = 4; //'1微信 2支付宝 3现金 4小程序微信 5其他支付方式 6会员余额', $item[$PayOrderModel::TRADE_AMOUNT] = $Wx; //'订单金额', $item[$PayOrderModel::TRADE_NO] = $wxPayOrder[$PayOrderModel::TRADE_NO]; //'订单微信支付宝流水号', $item[$PayOrderModel::M_PAY_TYPE] = $wxPayOrder[$PayOrderModel::M_PAY_TYPE]; //'订单支付类型 1普通商户模式 2服务商模式 3新大陆模式', $new_pay_order = $PayOrderModel->addPayOrder($item); if ($new_pay_order) { $PaySetModel = D('RetailPaySet'); $paySet = $PaySetModel->getFindMerchantPaySet($merchant_id);//支付设置 if ($paySet['status'] == 0) { return $paySet; } else { $out_refund_no = $new_pay_order[$PayOrderModel::OUT_TRADE_NO]; if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 3) { $new_pay_order['before_trade_no'] = $wxPayOrder[$PayOrderModel::OUT_TRADE_NO]; $new_pay_order['before_amount'] = $wxPayOrder[$PayOrderModel::TRADE_AMOUNT]; $res = A('Pay/PayContinent')->toOrderRefund_v3($new_pay_order); if ($res['status'] == 1) { $map = array($PayOrderModel::ID => $new_pay_order[$PayOrderModel::ID]); $save = array( $PayOrderModel::ORDER_STATE => 'REFUND', $PayOrderModel::TRADE_DATE => time() ); $PayOrderModel->updateOrder($map, $save); $PayOrderModel->toSetInc([ 'id' => $wxPayOrder[$PayOrderModel::ID] ], 'refund_money', $Wx); } $resultArr[] = $res; } else if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 4) { $new_pay_order['before_trade_no'] = $wxPayOrder[$PayOrderModel::OUT_TRADE_NO]; $new_pay_order['before_amount'] = $wxPayOrder[$PayOrderModel::TRADE_AMOUNT]; //云闪付 $payObj = new CloudPayController(); $res = $payObj->cloudRefund($new_pay_order, $paySet['config'], $item[$PayOrderModel::PAY_TYPE]); if ($res['status'] == 1) { $map = array($PayOrderModel::ID => $new_pay_order[$PayOrderModel::ID]); $save = array( $PayOrderModel::ORDER_STATE => 'REFUND', $PayOrderModel::TRADE_DATE => time() ); $PayOrderModel->updateOrder($map, $save); $PayOrderModel->toSetInc([ 'id' => $wxPayOrder[$PayOrderModel::ID] ], 'refund_money', $Wx); } $resultArr[] = $res; } else if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 5) { //乐返 $new_pay_order['before_amount'] = $wxPayOrder[$PayOrderModel::TRADE_AMOUNT]; $new_pay_order['before_trade_no'] = $wxPayOrder[$PayOrderModel::OUT_TRADE_NO]; $happyPay = new \HappyPay\Business\HappyPay(); $res = $happyPay->happyMoneyHandle($new_pay_order, $paySet['config']); if ($res['status'] == 1) { A('Pay/Base')->doRefundRate($new_pay_order['trade_no'], $new_pay_order['trade_amount'], 4);//乐返分润 } $resultArr[] = $res; } else if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 7) { //钱客云,小程序,售后订单退款 $new_pay_order['before_amount'] = $wxPayOrder[$PayOrderModel::TRADE_AMOUNT]; $new_pay_order['before_trade_no'] = $wxPayOrder[$PayOrderModel::OUT_TRADE_NO]; $moneyGuest = new \MoneyGuestPay\Business\MoneyGuest(); $res = $moneyGuest->moneyGuestRefund($new_pay_order, $paySet['config']); if($res['status'] == 1){ A('Pay/Base')->doRefundRate($new_pay_order['trade_no'], $new_pay_order['trade_amount'], 6);//钱客云分润 } $resultArr[] = $res; } else { $payConfig = $paySet['config']; if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 1 || $wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 0) { $key = $payConfig[$PaySetModel::XCX_SECRET_KEY]; $post['appid'] = $payConfig[$PaySetModel::XCX_APPID]; $post['mch_id'] = $payConfig[$PaySetModel::XCX_MCH_ID]; $apiclient_cert = $payConfig[$PaySetModel::XCX_AC_CERT]; $apiclient_key = $payConfig[$PaySetModel::XCX_AC_KEY]; } else { $SystemConfigModel = D('SystemConfig'); $systemConfig = $payConfig['systemConfig']; $post['appid'] = $systemConfig[$SystemConfigModel::WX_APPID]; $post['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID]; $post['sub_mch_id'] = $payConfig[$PaySetModel::XCX_SUB_MCH_ID]; $post['sub_appid'] = $payConfig[$PaySetModel::XCX_SUB_APPID]; $key = $systemConfig[$SystemConfigModel::WX_KEY]; $apiclient_cert = $systemConfig[$SystemConfigModel::WX_AC_CERT]; $apiclient_key = $systemConfig[$SystemConfigModel::WX_AC_KEY]; } $post['nonce_str'] = createKey(); $post['out_refund_no'] = $out_refund_no; $post['out_trade_no'] = $wxPayOrder[$PayOrderModel::OUT_TRADE_NO]; $post['spbill_create_ip'] = $_SERVER['SERVER_ADDR']; //服务器终端的ip $post['total_fee'] = $wxPayOrder[$PayOrderModel::TRADE_AMOUNT] * 100; //总金额 最低为一分钱 必须是整数 $post['refund_fee'] = $Wx * 100; $sign = createSign($post, $key); //生成签名 $post['sign'] = $sign; $post_xml = arrToXml($post); $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund'; $xml = http_cert_request($url, $post_xml, $apiclient_cert, $apiclient_key);//POST方式请求http $array = xmlToArray($xml); file_put_contents('./xcxRefund.txt', date('Y-m-d H:i:s') . ' array: ' . json_encode([$array, $url, $post_xml, $apiclient_cert, $apiclient_key, $merchant_id]) . "\r\n", FILE_APPEND); if ($array['return_code'] == "SUCCESS" && $array['result_code'] == "SUCCESS") { if ($wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 1 || $wxPayOrder[$PayOrderModel::M_PAY_TYPE] == 0) { $search['appid'] = $payConfig[$PaySetModel::XCX_APPID]; $search['mch_id'] = $payConfig[$PaySetModel::XCX_MCH_ID]; } else { $search['appid'] = $systemConfig[$SystemConfigModel::WX_APPID]; $search['mch_id'] = $systemConfig[$SystemConfigModel::MCH_ID]; $search['sub_mch_id'] = $payConfig[$PaySetModel::XCX_SUB_MCH_ID]; $search['sub_appid'] = $payConfig[$PaySetModel::XCX_SUB_APPID]; } $search['nonce_str'] = createKey(); $search['transaction_id'] = $array['transaction_id']; $sign = createSign($search, $key); //签名 $search['sign'] = $sign; $search_xml = arrToXml($search); $url = 'https://api.mch.weixin.qq.com/pay/refundquery'; $xml = http_request($url, $search_xml, $apiclient_cert, $apiclient_key); //POST方式请求http $search_res = xmlToArray($xml); // $result['search'] = $res; file_put_contents('./xcxRefund.txt', date('Y-m-d H:i:s') . ' search_res: ' . json_encode([$search_res, $url, $search_xml, $apiclient_cert, $apiclient_key, $merchant_id]) . "\r\n", FILE_APPEND); if ($search_res['return_code'] == "SUCCESS" && $search_res['result_code'] == "SUCCESS") { switch ($search_res['refund_status_0']) { case 'SUCCESS': case 'PROCESSING': $result['status'] = 1; $result['refund_no'] = $search_res['refund_id_0']; $result['msg'] = '退款成功'; $PayOrderModel->toSetInc([ 'id' => $wxPayOrder[$PayOrderModel::ID] ], 'refund_money', $Wx); $map = array($PayOrderModel::ID => $new_pay_order[$PayOrderModel::ID]); $save = array( $PayOrderModel::TRADE_NO => $search_res['refund_id_0'], $PayOrderModel::ORDER_STATE => 'REFUND', $PayOrderModel::TRADE_DATE => time() ); if ($array['coupon_refund_count'] > 0) { //代金券修改状态 $PayCouponClass = new PaymentRefund(); $couponResult = $PayCouponClass->paymentRefund(json_encode([ 'refund_info' => $array, 'merchant_id' => $merchant_id, 'type' => 1, 'old_pay_order_id' => $wxPayOrder['id'] ])); if ($couponResult['status'] == 1) { $save['trade_amount'] = $couponResult['data']['cash_fee']; $save['pay_coupon_id_str'] = $couponResult['data']['pay_coupon_id_str']; $save['pay_coupon_fee'] = $wxPayOrder['pay_coupon_fee']; $save['refund_coupon_fee'] = $couponResult['data']['pay_coupon_fee']; //退款代金券退还的金额 $PayOrderModel->toSetInc([ 'id' => $wxPayOrder['id'] ], 'refund_coupon_fee', $couponResult['data']['pay_coupon_fee']); $PayOrderModel->toSetDec([ 'id' => $wxPayOrder['id'] ], 'refund_money', $couponResult['data']['pay_coupon_fee']); $pay_coupon_info = [ 'pay_coupon_id_str' => $couponResult['data']['pay_coupon_id_str'], 'refund_coupon_fee' => $couponResult['data']['pay_coupon_fee'] ]; } } $PayOrderModel->updateOrder($map, $save); break; case 'REFUNDCLOSE': $result['status'] = 0; $result['msg'] = '退款关闭'; break; case 'CHANGE': $result['status'] = 0; $result['msg'] = '退款异常,请到商户品台手动处理'; default: $result['status'] = 0; $result['msg'] = '退款失败'; } } else { $result['status'] = 0; $result['msg'] = '退款失败'; } $resultArr[] = $result; } else { $result['return'] = $array; $result['status'] = 0; $result['msg'] = $array['err_code_des'] ? $array['err_code_des'] : ($array['return_msg'] ? $array['return_msg'] : '退款失败'); $resultArr[] = $result; } } } } else { $res['status'] = 0; $res['msg'] = '微信退款记录添加失败'; $resultArr[] = $res; } } if (!empty($bPayOrder) && $balance > 0) { //余额退款 $item[$PayOrderModel::PAY_ORDER_ID] = $bPayOrder[$PayOrderModel::ID]; $item[$PayOrderModel::PAY_TYPE] = 6; //'1微信 2支付宝 3现金 4小程序微信 5其他支付方式 6会员余额', $item[$PayOrderModel::TRADE_AMOUNT] = $balance; //'订单金额', $new_pay_order = $PayOrderModel->addPayOrder($item); if ($new_pay_order) { $res = A('PayApi/VipPay')->refundForVip_v1($new_pay_order, 4, 5); if ($res['status'] == 1) { $PayOrderModel->toSetInc([ 'id' => $bPayOrder['id'] ], 'refund_money', $balance); $map = array($PayOrderModel::ID => $new_pay_order[$PayOrderModel::ID]); $save = array( $PayOrderModel::ORDER_STATE => 'REFUND', $PayOrderModel::TRADE_DATE => time() ); $PayOrderModel->updateOrder($map, $save); } } else { $res['status'] = 0; $res['msg'] = '余额退款记录添加失败'; } $resultArr[] = $res; if ($pay_type) { $pay_type = 8; } else { $pay_type = 5; } } $status = 0; $msg = ''; foreach ($resultArr as $value) { if ($value['status']) { $status = 1; } $msg .= $value['msg'] . ','; } $res = array( 'status' => $status, 'msg' => trim($msg, ','), 'pay_type' => $pay_type, 'return_info' => $array, 'pay_coupon_info' => $pay_coupon_info ? $pay_coupon_info : [] ); return $res; } /** * 2019-11-11购买plus会员支付成功回调 * @param $pay_order * @return bool */ public function plus_continent_pay_v2($pay_order) { if (empty($pay_order)) { return false; } if (is_array($pay_order)) { $PayOrderModel = D('RetailPayOrder'); $pay_order_id = $pay_order[$PayOrderModel::ID]; } else { $pay_order_id = $pay_order; } // 查询付费记录 $PlusRecordModel = D('RetailPlusRecord'); $rMap = array( $PlusRecordModel::PAY_ORDER_ID => $pay_order_id, $PlusRecordModel::PAY_STATE => 0 ); $record = $PlusRecordModel->getFind($rMap); if (empty($record)) { $res['status'] = 0; $res['msg'] = '记录查询失败'; return $res; } // 修改plus_record表支付状态 $upItem = array( $PlusRecordModel::PAY_STATE => 1, $PlusRecordModel::PAY_TYPE => 1, ); $save1 = $PlusRecordModel->updateOrder($rMap, $upItem); if (!$save1) { $res['status'] = 0; $res['msg'] = '订单更新失败'; return $res; } $PlusVipModel = D('RetailPlusVip'); $PlusActivityModel = D('PlusActivity'); $cMap = array( $PlusActivityModel::ID => $record[$PlusRecordModel::ACTIVITY_ID], ); $plus_time = $PlusActivityModel->getFindField($cMap, $PlusActivityModel::TIME); $plus_time = $plus_time * 86400; if ($record[$PlusRecordModel::TYPE] == 1) { // 开通 $flag = false; if (!empty($record['vip_id'])) { //判断是否曾经购买过plus会员、过期后续费 $plus_vip = $PlusVipModel->getFind(['vip_id' => $record['vip_id']]); if (!empty($plus_vip)) { $flag = true; } } $time = time(); if ($flag) { $up1[$PlusVipModel::STATE] = 1; $up1[$PlusVipModel::START_TIME] = $time; $up1[$PlusVipModel::END_TIME] = $time + $plus_time; $plus_id = $plus_vip['id']; $PlusVipModel->updateOrder(array($PlusVipModel::ID => $plus_id), $up1); } else { $plusItem = array( $PlusVipModel::VIP_ID => $record[$PlusRecordModel::VIP_ID], $PlusVipModel::XCX_VIP_ID => $record[$PlusRecordModel::XCX_UID], $PlusVipModel::MERCHANT_ID => $record[$PlusRecordModel::MERCHANT_ID], $PlusVipModel::STORE_ID => $record[$PlusRecordModel::STORE_ID], $PlusVipModel::ADD_TIME => $time, $PlusVipModel::START_TIME => $time, $PlusVipModel::END_TIME => $time + $plus_time, ); $plus_id = $PlusVipModel->addOrder($plusItem); } if (!$plus_id) { $res['status'] = 0; $res['msg'] = '添加Plus用户失败'; return $res; } } else if ($record[$PlusRecordModel::TYPE] == 2) { // 续费 $pMap = array( $PlusVipModel::VIP_ID => $record[$PlusRecordModel::VIP_ID] ); $plus = $PlusVipModel->getFind($pMap); if (!$plus) { $res['status'] = 0; $res['msg'] = 'plus会员查询失败'; return $res; } $plus_id = $plus['id']; $time = time(); if ($plus[$PlusVipModel::END_TIME] > $time) { //没过期 $up1[$PlusVipModel::END_TIME] = $plus[$PlusVipModel::END_TIME] + $plus_time; } else { //已过期 $up1[$PlusVipModel::END_TIME] = $time + $plus_time; } $up1[$PlusVipModel::STATE] = 1; $up1[$PlusVipModel::START_TIME] = $time; $pMap = array( $PlusVipModel::ID => $plus[$PlusVipModel::ID], ); $save4 = $PlusVipModel->updateOrder($pMap, $up1); if (!$save4) { $res['status'] = 0; $res['msg'] = '过期日期修改失败'; return $res; } } // 改变用户类型 $RSPUModel = new RetailSmallProgramUserModel(); $uMap = [ 'vid' => $record['vip_id'], ]; $nUp = [ 'type' => 2, 'plus_vip_id' => $plus_id, ]; $RSPUModel->updateOrder($uMap, $nUp); // 改变会员类型 $VipModel = new RetailVipModel(); $vMap = array( 'id' => $record['vip_id'] ); $vUp = array( 'plus_id' => $plus_id, 'plus_type' => 2, 'plus_state' => 1, ); $save3 = $VipModel->updateOrder($vMap, $vUp); if (!$save3) { $res['status'] = 0; $res['msg'] = '会员类型变更失败'; } else { $res['status'] = 1; $res['msg'] = '购买成功'; } return $res; } }