审查视图

application/api/controller/Pay.php 13.8 KB
1 2 3 4
<?php

namespace app\api\controller;
jinglong authored
5
use app\admin\model\Order;
6 7 8 9
use app\common\controller\Api;
use EasyWeChat\Factory;
use think\Validate;
use function EasyWeChat\Kernel\Support\generate_sign;
jinglong authored
10
use think\Log;
11 12 13 14 15
/**
 * 支付接口
 */
class Pay extends Api
{
jinglong authored
16
    protected  $noNeedLogin = ['payOrderNotify','purchaseNotify'];
17 18 19 20 21 22 23
    protected $noNeedRight = ['*'];
    protected $uid = '';//token存贮uid
    protected $order_status = [];//订单状态
    public function _initialize()
    {
        parent::_initialize();
        $this->uid = $this->auth->getUserId();
jinglong authored
24
        $this->order_status = config('verify.status');
25 26 27
    }

    /**
jinglong authored
28 29
     * @ApiTitle    (支付订单)
     * @ApiSummary  (支付订单)
30 31 32 33 34
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/pay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="openid", type="string", required=true, description="小程序openid")
jinglong authored
35
     * @ApiParams   (name="order_sn", type="inter", required=true, description="订单号")
36
     *
jinglong authored
37 38 39 40 41 42 43 44 45 46
     * @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="实付总金额")
     *
     *
47 48 49
     */
    public function pay(){
        if($this->request->isPost()){
jinglong authored
50
            $data = $this->request->post();
jinglong authored
51
            $rule = config('verify.pay');
52
            $validate = new Validate($rule['rule'],$rule['msg']);
jinglong authored
53
            if (!$validate->check($data)) {
54 55 56
                $this->error($validate->getError());
            }
jinglong authored
57 58 59
            $order_sn = $data['order_sn'];
            $openid = $data['openid'];
jinglong authored
60 61 62
            $ffg_host = config('verify.ffg_host');
            $status = $this->order_status;
            //支付订单
jinglong authored
63
            $res = Common::findSoftWhereData('order',['uid'=>$this->uid,'order_sn'=>$order_sn,'status'=>$status[0]],'id,total_price');
jinglong authored
64 65
            if(!$res){
                $this->error('无效的订单');
66
            }
jinglong authored
67
jinglong authored
68 69 70 71 72 73 74
            //检测库存
            $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);
            }
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109

            $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){
jinglong authored
110
                    $arr['status'] = $status[2];
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
                    $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('失败');
                    }
                }
            }

127 128 129 130
            //创建支付对象
            $config = config('verify.wx_pay');
            $app = Factory::payment($config);
            $result = $app->order->unify([
jinglong authored
131
                'body' => 'VIVAKOOL非凡谷商品',
jinglong authored
132
                'out_trade_no' => $pay_order_sn,//支付订单号
jinglong authored
133
//                'total_fee' => $res['total_price']*100,//单位分
jinglong authored
134
                'total_fee' => 1,//单位分
jinglong authored
135
                'notify_url' => $ffg_host.'/api/pay/payOrderNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
136 137 138 139 140 141 142 143 144 145 146 147 148
                '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']);
jinglong authored
149
jinglong authored
150
                $res1 = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update($arr);
jinglong authored
151
                if($res1){
jinglong authored
152 153
                    $res2 = Common::findSoftWhereData('order',['order_sn'=>$order_sn,'uid'=>$this->uid],'id order_id');
                    $this->success('成功',['data'=>$params,'order_id'=>$res2['order_id']]);
jinglong authored
154 155 156
                }else{
                    $this->error('失败');
                }
157 158 159 160 161 162 163
            }
            $this->error($result['err_code_des']);
        }else{
            $this->error('请求方式错误');
        }
    }
jinglong authored
164 165 166 167
    /**
     * 支付订单回调
     * @ApiInternal
     */
168 169 170 171 172 173 174 175
    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') {
jinglong authored
176
                    //支付成功,更新订单号,销量增加1
jinglong authored
177
                    Common::paySuccess($message['out_trade_no']);
178 179 180 181 182 183 184 185 186 187 188 189
                }elseif($message['result_code'] === 'FAIL') {
                    //支付失败
                }
            } else {
                return $fail('通信失败,请稍后再通知我');
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

    /**
jinglong authored
190 191
     * @ApiTitle    (立即购买)
     * @ApiSummary  (立即购买)
192
     * @ApiMethod   (POST)
jinglong authored
193
     * @ApiRoute    (/api/pay/purchase)
194 195
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
jinglong authored
196 197 198
     * @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="收货地址")
199
     * @ApiParams   (name="openid", type="string", required=true, description="小程序openid")
jinglong authored
200 201 202
     * @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)")
jinglong authored
203
     * @ApiParams   (name="style", type="string", required=true, description="商品款式(多个以逗号隔开,如:‘款式1,款式2,款式3’)")
jinglong authored
204
     * @ApiParams   (name="leave_message", type="string", required=false, description="留言")
jinglong authored
205
     * @ApiParams   (name="coupon_id", type="inter", required=false, description="优惠券id")
jinglong authored
206 207
     *
     * @ApiParams   (name="total_goods_price", type="inter", required=true, description="商品总金额")
jinglong authored
208
     * @ApiParams   (name="discount_price", type="inter", required=true, description="优惠金额")
jinglong authored
209
     * @ApiParams   (name="total_expense_price", type="inter", required=true, description="运费总金额")
jinglong authored
210
     * @ApiParams   (name="total_price", type="inter", required=true, description="实付总金额")
211
     */
jinglong authored
212
    public function purchase(){
213 214 215
        if($this->request->isPost()){
            $data = $this->request->post();
jinglong authored
216
            $rule = config('verify.purchase');
217 218 219 220 221
            $validate = new Validate($rule['rule'],$rule['msg']);
            if (!$validate->check($data)) {
                $this->error($validate->getError());
            }
jinglong authored
222 223 224 225 226 227 228 229 230 231 232 233 234
            //检测库存
            $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);
            }
235 236 237 238 239 240 241 242 243 244 245 246
            //支付金额为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']]);
                }
            }
jinglong authored
247
248 249 250
            //创建支付对象
            $config = config('verify.wx_pay');
            $app = Factory::payment($config);
jinglong authored
251 252
            $ffg_host = config('verify.ffg_host');
            $result = $app->order->unify([
jinglong authored
253
                'body' => 'VIVAKOOL非凡谷商品',
jinglong authored
254
                'out_trade_no' => $pay_order_sn,//支付订单号
jinglong authored
255
//                'total_fee' => $data['total_price']*100,//单位分
jinglong authored
256
                'total_fee' => 1,//单位分
jinglong authored
257 258 259 260
                'notify_url' => $ffg_host.'/api/pay/purchaseNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $data['openid'],
            ]);
jinglong authored
261
jinglong authored
262 263 264 265 266 267 268 269 270 271 272 273 274
            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){
jinglong authored
275
                    $this->success('成功',['data'=>$params,'order_id'=>$res['order_id']]);
jinglong authored
276 277 278 279
                }
                $this->error('创建订单失败');
            }
            $this->error($result['err_code_des']);
280 281 282 283 284
        }else{
            $this->error('请求方式错误');
        }
    }
jinglong authored
285 286 287 288
    /**
     * 立即购买回调
     * @ApiInternal
     */
jinglong authored
289
    public function purchaseNotify(){
290 291
        $config = config('verify.wx_pay');
        $app = Factory::payment($config);
jinglong authored
292
        Log::info(1111);
293
        $response = $app->handlePaidNotify(function($message, $fail){
jinglong authored
294 295

            Log::info($message);
296 297 298
            //return_code 表示通信状态
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
jinglong authored
299
                    //支付成功,更新订单号,销量增加1
jinglong authored
300
                    Common::paySuccess($message['out_trade_no']);
301 302 303 304 305 306 307 308 309 310 311 312
                }elseif($message['result_code'] === 'FAIL') {
                    //支付失败,好像有问题
                }
            } else {
                return $fail('通信失败,请稍后再通知我');
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

}