<?php namespace App\Models; use App\Command\Log; use EasyWeChat\Factory; use Illuminate\Support\Facades\DB; use App\Models\Good as GoodModel; use App\Models\GoodSku; class Pay { private static function getConfig() { return $config = [ // 必要配置 'app_id' => env('WX_XCX_APPID'), 'mch_id' => env('WX_XCX_MCH_ID'), 'key' => env('WX_XCX_MCH_KEY'), // API v2 密钥 (注意: 是v2密钥 是v2密钥 是v2密钥) // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书) 'cert_path' => public_path() . '/cert/apiclient_cert.pem', // XXX: 绝对路径!!!! 'key_path' => public_path() . '/cert/apiclient_key.pem', // XXX: 绝对路径!!!! 'notify_url' => '/', // 你也可以在下单时单独设置来想覆盖它 ]; } public static function pay($body, $order_sn, $order_price, $openid) { $orderPrice = intval(strval($order_price * 100)); $app = Factory::payment(self::getConfig()); $jssdk = $app->jssdk; $result = $app->order->unify([ 'body' => $body, 'out_trade_no' => $order_sn, // 'total_fee' => $order_price*100, 'total_fee' => $orderPrice, // 'spbill_create_ip' => '123.12.12.123', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 //'notify_url' => 'https://pay.weixin.qq.com/wxpay/pay.action', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $openid, 'notify_url' => env('API_URL') . '/pay-notify', ]); Log::add('订单支付_', $result); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { $prepayId = $result['prepay_id']; $config = $jssdk->sdkConfig($prepayId); return $config; } if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) { throw new \Exception($result['return_msg']); } throw new \Exception($result['err_code_des']); } public static function payNotify($fields = []) { $app = Factory::payment(self::getConfig()); $response = $app->handlePaidNotify(function ($message, $fail) { Log::add('--支付回调--', $message); $orderObj = OrderInfo::where(['order_sn' => $message['out_trade_no']])->first(); if (!$orderObj) { $fail('订单不存在'); } //支付完成后的业务逻辑[result_code] => SUCCESS if ($orderObj->pay_status == 1) { return true; } if ($message['result_code'] == "SUCCESS") { DB::beginTransaction(); try { //更新订单 if ($orderObj->pay_status == 0) { $orderObj->order_status = 1; $orderObj->pay_status = 1; if ($orderObj->save()) { //更新商品销量、库存 $goodsList = OrderGoods::where("order_id", $orderObj->id)->get(); foreach ($goodsList as $item) { //Log::add('--订单商品对象--', $item); $gid = $item->goods_id; $attr_id = $item->attr_id; $mer_id = $item->merchant_id; $goods_number = $item->goods_number; //更新此商品支付状态 $item->is_pay = 1; $item->save(); $goodsObj = GoodModel::find($gid); //更新商品规格库存 $attrObj = GoodSku::find($attr_id); $attr_stock = ($attrObj->stock - $goods_number) >= 0 ? $attrObj->stock - $goods_number : 0; $attrObj->stock = $attr_stock; $attrObj->save(); //更新商品sku $skuArr = json_decode($goodsObj->sku, true); if ($skuArr['sku']) { foreach ($skuArr['sku'] as $kk => $vv) { if (isset($vv['attr_sn']) && $vv['attr_sn'] == $attrObj->attr_sn) { $skuArr['sku'][$kk]['stock'] = $attr_stock; } } $goodsObj->sku = json_encode($skuArr, JSON_UNESCAPED_UNICODE); $goodsObj->save(); } //商户规格库存 $mgsObj = MerchantGoodSku::where(['goods_id' => $gid, 'attr_id' => $attr_id, 'merchant_id' => $mer_id])->first(); if ($mer_id && $mgsObj) { $changeStock = ($mgsObj->stock >= $goods_number) ? $mgsObj->stock - $goods_number : 0; $mgsObj->stock = $changeStock; $mgsObj->save(); } } } } //支付记录 $pay_cord = new PaymentRecord(); $cordLog = $pay_cord->where(['order_sn' => $message['out_trade_no']])->first(); if (!$cordLog) { $total_fee = $message['total_fee']; $pay_money = round($total_fee / 100, 2); $pay_cord->order_sn = $message['out_trade_no']; $pay_cord->other_order = $message['transaction_id']; $pay_cord->money = $pay_money; $pay_cord->uid = $orderObj->user_id; $pay_cord->save(); } DB::commit(); //return true; } catch (\Exception $e) { Log::add('付款回调失败', $e); DB::rollBack(); return false; } } return true; }); //Log::add('响应结果', $response); //Log::add('响应结果内容', $response->getContent()); $response->send(); return $response; } public static function refund($wxOrder_no, $orderPrice, $refundPrice) { $app = Factory::payment(self::getConfig()); $refund_no = date('YmdHis') . rand(100000, 999999); $orderPrice = intval(strval($orderPrice * 100)); $refundPrice = intval(strval($refundPrice * 100)); $result = $app->refund->byTransactionId($wxOrder_no, $refund_no, $orderPrice, $refundPrice, [ // 可在此处传入其他参数,详细参数见微信支付文档 'refund_desc' => '订单退款', 'notify_url' => env('API_URL') . '/refund-notify', ]); // echo '<pre>'; // print_r($result); Log::add('订单退款', $result); if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { //退款成功的操作 return $result; } if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) { throw new \Exception($result['return_msg']); } throw new \Exception($result['err_code_des']); } public static function refundNotify($fields) { $app = Factory::payment(self::getConfig()); $response = $app->handleRefundedNotify(function ($message, $fail) use ($fields) { return true; }); return $response; } //提现 public static function toBalance($openid, $amount, $desc) { $out_batch_no = 'tx' . date('Ymd') . mt_rand(1000, 9999); $partner_trade_no = date('YmdHis') . rand(1000, 9999); $pay_v3 = new PayV3(); $res = $pay_v3->transfer($out_batch_no, $partner_trade_no, $amount, $openid, $desc); Log::add('提现微信返回值', $res); if (isset($res['batch_id'])) { return [$partner_trade_no, $out_batch_no, $res['batch_id'], $res['batch_status']]; } throw new \Exception('提现失败'); } }