<?php namespace app\api\controller; use app\admin\model\Order; use app\common\controller\Api; use EasyWeChat\Factory; use think\Validate; use function EasyWeChat\Kernel\Support\generate_sign; use think\Log; /** * 支付接口 */ class Pay extends Api { protected $noNeedLogin = ['payOrderNotify','purchaseNotify']; protected $noNeedRight = ['*']; protected $uid = '';//token存贮uid protected $order_status = [];//订单状态 public function _initialize() { parent::_initialize(); $this->uid = $this->auth->getUserId(); $this->order_status = config('verify.status'); } /** * @ApiTitle (支付订单) * @ApiSummary (支付订单) * @ApiMethod (POST) * @ApiRoute (/api/pay/pay) * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") * * @ApiParams (name="openid", type="string", required=true, description="小程序openid") * @ApiParams (name="order_sn", type="inter", required=true, description="订单号") * * @ApiParams (name="receive_name", type="string", required=false, description="收货人") * @ApiParams (name="receive_mobile", type="string", required=false, description="联系方式") * @ApiParams (name="receive_address", type="string", required=false, description="收货地址") * @ApiParams (name="leave_message", type="string", required=false, description="留言") * @ApiParams (name="coupon_id", type="inter", required=false, description="优惠券id") * * @ApiParams (name="discount_price", type="inter", required=false, description="优惠金额") * @ApiParams (name="total_price", type="inter", required=false, description="实付总金额") * * */ public function pay(){ if($this->request->isPost()){ $data = $this->request->post(); $rule = config('verify.pay'); $validate = new Validate($rule['rule'],$rule['msg']); if (!$validate->check($data)) { $this->error($validate->getError()); } $order_sn = $data['order_sn']; $openid = $data['openid']; $ffg_host = config('verify.ffg_host'); $status = $this->order_status; //支付订单 $res = Common::findSoftWhereData('order',['uid'=>$this->uid,'order_sn'=>$order_sn,'status'=>$status[0]],'id,total_price'); if(!$res){ $this->error('无效的订单'); } //检测库存 $order_goods = Common::selectSoftWhereData('ogoods',['o_id'=>$res['id']],'id,g_id goods_id,style,goods_number'); $check_stock = Common::checkPayStock($order_goods); if(!$check_stock){ $this->error($check_stock); } $orderModel = new Order(); $pay_order_sn = Common::genPayOrderSn('pay');//支付订单号 //更新订单的支付订单号 $arr = []; $arr['pay_order_sn'] = $pay_order_sn; if(isset($data['receive_name']) && !empty($data['receive_name'])){ //收货人 $arr['receive_name'] = $data['receive_name']; } if(isset($data['receive_mobile']) && !empty($data['receive_mobile'])){ //收货电话 $arr['receive_mobile'] = $data['receive_mobile']; } if(isset($data['receive_address']) && !empty($data['receive_address'])){ //收货地址 $arr['receive_address'] = $data['receive_address']; } if(isset($data['leave_message']) && !empty($data['leave_message'])){ //留言 $arr['leave_message'] = $data['leave_message']; } if(isset($data['coupon_id']) && !empty($data['coupon_id'])){ //优惠券id $arr['coupon_id'] = $data['coupon_id']; } if(isset($data['discount_price']) && !empty($data['discount_price'])){ //优惠价格 $arr['discount_price'] = $data['discount_price']; } if(isset($data['total_price']) && !empty($data['total_price'])){ //支付总金额 $arr['total_price'] = $data['total_price']; //支付金额为0,直接更新为支付成功 if($data['total_price'] == 0){ $arr['status'] = $status[2]; $res1 = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update($arr); if($res1){ $res2 = Common::findSoftWhereData('order',['order_sn'=>$order_sn,'uid'=>$this->uid],'id order_id'); if($res2){ Common::paySuccess($pay_order_sn); $this->success('成功',['order_id'=>$res2['order_id']]); }else{ $this->error('未查到订单'); } }else{ $this->error('失败'); } } } //创建支付对象 $config = config('verify.wx_pay'); $app = Factory::payment($config); $result = $app->order->unify([ 'body' => 'VIVAKOOL非凡谷商品', 'out_trade_no' => $pay_order_sn,//支付订单号 // 'total_fee' => $res['total_price']*100,//单位分 'total_fee' => 1,//单位分 'notify_url' => $ffg_host.'/api/pay/payOrderNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $openid, ]); if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){ $params = [ 'appId' => $config['app_id'], 'timeStamp' => time(), 'nonceStr' => $result['nonce_str'], // 统一下单返回的随机字符串 'package' => 'prepay_id='.$result['prepay_id'], // 统一下单Id 'signType' => 'MD5', // 签名方法 ]; // 注意这里用的是商户平台的Key进行二次签名 $params['paySign'] = generate_sign($params, $config['key']); $res1 = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update($arr); if($res1){ $res2 = Common::findSoftWhereData('order',['order_sn'=>$order_sn,'uid'=>$this->uid],'id order_id'); $this->success('成功',['data'=>$params,'order_id'=>$res2['order_id']]); }else{ $this->error('失败'); } } $this->error($result['err_code_des']); }else{ $this->error('请求方式错误'); } } /** * 支付订单回调 * @ApiInternal */ public function payOrderNotify(){ $config = config('verify.wx_pay'); $app = Factory::payment($config); $response = $app->handlePaidNotify(function($message, $fail){ //return_code 表示通信状态 if ($message['return_code'] === 'SUCCESS') { if ($message['result_code'] === 'SUCCESS') { //支付成功,更新订单号,销量增加1 Common::paySuccess($message['out_trade_no']); }elseif($message['result_code'] === 'FAIL') { //支付失败 } } else { return $fail('通信失败,请稍后再通知我'); } return true; // 返回处理完成 }); $response->send(); } /** * @ApiTitle (立即购买) * @ApiSummary (立即购买) * @ApiMethod (POST) * @ApiRoute (/api/pay/purchase) * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") * * @ApiParams (name="receive_name", type="string", required=true, description="收货人") * @ApiParams (name="receive_mobile", type="string", required=true, description="联系方式") * @ApiParams (name="receive_address", type="string", required=true, description="收货地址") * @ApiParams (name="openid", type="string", required=true, description="小程序openid") * @ApiParams (name="goods_id", type="string", required=true, description="商品id(多个以逗号隔开,如:1,3,4)") * @ApiParams (name="price", type="string", required=true, description="商品价格(多个以逗号隔开,如:100,10,200)") * @ApiParams (name="goods_number", type="string", required=true, description="商品数量(多个以逗号隔开,如:10,10,10)") * @ApiParams (name="style", type="string", required=true, description="商品款式(多个以逗号隔开,如:‘款式1,款式2,款式3’)") * @ApiParams (name="leave_message", type="string", required=false, description="留言") * @ApiParams (name="coupon_id", type="inter", required=false, description="优惠券id") * * @ApiParams (name="total_goods_price", type="inter", required=true, description="商品总金额") * @ApiParams (name="discount_price", type="inter", required=true, description="优惠金额") * @ApiParams (name="total_expense_price", type="inter", required=true, description="运费总金额") * @ApiParams (name="total_price", type="inter", required=true, description="实付总金额") */ public function purchase(){ if($this->request->isPost()){ $data = $this->request->post(); $rule = config('verify.purchase'); $validate = new Validate($rule['rule'],$rule['msg']); if (!$validate->check($data)) { $this->error($validate->getError()); } //检测库存 $goods_id_s = explode(',',$data['goods_id']); $price_s = explode(',',$data['price']); $goods_number_s = explode(',',$data['goods_number']); $style_s = explode(',',$data['style']); //合并数组 $key = ['goods_id','price','goods_number','style']; $res_goods = Common::array_merge_more($key,$goods_id_s,$price_s,$goods_number_s,$style_s); $check_stock = Common::checkPayStock($res_goods,$goods_id_s); if(!$check_stock){ $this->error($check_stock); } //支付金额为0,直接更新为支付成功 $pay_order_sn = Common::genPayOrderSn('pay');//支付订单号 if($data['total_price'] == 0){ //写入订单 $status = config('verify.status'); $res = Common::createOrder($data,$pay_order_sn,$this->uid,$status[2]); if($res){ Common::paySuccess($pay_order_sn); $this->success('成功',['order_id'=>$res['order_id']]); } } //创建支付对象 $config = config('verify.wx_pay'); $app = Factory::payment($config); $ffg_host = config('verify.ffg_host'); $result = $app->order->unify([ 'body' => 'VIVAKOOL非凡谷商品', 'out_trade_no' => $pay_order_sn,//支付订单号 // 'total_fee' => $data['total_price']*100,//单位分 'total_fee' => 1,//单位分 'notify_url' => $ffg_host.'/api/pay/purchaseNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $data['openid'], ]); if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){ $params = [ 'appId' => $config['app_id'], 'timeStamp' => time(), 'nonceStr' => $result['nonce_str'], // 统一下单返回的随机字符串 'package' => 'prepay_id='.$result['prepay_id'], // 统一下单Id 'signType' => 'MD5', // 签名方法 ]; // 注意这里用的是商户平台的Key进行二次签名 $params['paySign'] = generate_sign($params, $config['key']); //写入订单 $res = Common::createOrder($data,$pay_order_sn,$this->uid); if($res){ $this->success('成功',['data'=>$params,'order_id'=>$res['order_id']]); } $this->error('创建订单失败'); } $this->error($result['err_code_des']); }else{ $this->error('请求方式错误'); } } /** * 立即购买回调 * @ApiInternal */ public function purchaseNotify(){ $config = config('verify.wx_pay'); $app = Factory::payment($config); Log::info(1111); $response = $app->handlePaidNotify(function($message, $fail){ Log::info($message); //return_code 表示通信状态 if ($message['return_code'] === 'SUCCESS') { if ($message['result_code'] === 'SUCCESS') { //支付成功,更新订单号,销量增加1 Common::paySuccess($message['out_trade_no']); }elseif($message['result_code'] === 'FAIL') { //支付失败,好像有问题 } } else { return $fail('通信失败,请稍后再通知我'); } return true; // 返回处理完成 }); $response->send(); } }