config = $config; $this->app = Factory::payment([ 'app_id' => $config['appid'], //应用id 'mch_id' => $config["mch_id"] ?? '', //商户号 'key' => $config["pay_signkey"] ?? '', // API 密钥 // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书) 'cert_path' => realpath($config["apiclient_cert"]) ?? '', // apiclient_cert.pem XXX: 绝对路径!!!! 'key_path' => realpath($config["apiclient_key"]) ?? '', // apiclient_key.pem XXX: 绝对路径!!!! 'notify_url' => '',// 你也可以在下单时单独设置来想覆盖它 'response_type' => 'array', 'log' => [ 'level' => 'debug', 'permission' => 0777, 'file' => 'runtime/log/wechat/easywechat.logs', ], 'sandbox' => false, // 设置为 false 或注释则关闭沙箱模式 ]); } /** * 支付 * @param array $param * @return array\ */ public function pay(array $param){ $data = [ 'body' => str_sub($param["pay_body"], 15), 'out_trade_no' => $param["out_trade_no"], 'total_fee' => $param["pay_money"] * 100, 'notify_url' => $param["notify_url"], 'trade_type' => $param["trade_type"] == 'APPLET' ? 'JSAPI' : $param["trade_type"] ]; if ($param['trade_type'] == 'JSAPI' || $param['trade_type'] == 'APPLET') $data['openid'] = $param['openid']; $result = $this->app->order->unify($data); if ($result["return_code"] == 'FAIL') return $this->error([], $result["return_msg"]); if ($result["result_code"] == 'FAIL') return $this->error([], $result["err_code_des"]); $return = []; switch ($param["trade_type"]) { case 'JSAPI' ://微信支付 或小程序支付 $return = [ "type" => "jsapi", "data" => $this->app->jssdk->sdkConfig($result['prepay_id'], false) ]; break; case 'APPLET' ://微信支付 或小程序支付 $return = [ "type" => "jsapi", "data" => $this->app->jssdk->bridgeConfig($result['prepay_id'], false) ]; break; case 'NATIVE' : $upload_model = new Upload($param['site_id']); $qrcode_result = $upload_model->qrcode($result['code_url']); $return = [ "type" => "qrcode", "qrcode" => $qrcode_result['data'] ?? '' ]; break; case 'MWEB' ://H5支付 $return = [ "type" => "url", "url" => $result['mweb_url'] ]; break; case 'APP' : $config = $this->app->jssdk->appConfig($result['prepay_id']); $return = [ "type" => "app", "data" => $config ]; break; } return $this->success($return); } /** * 异步回调 */ public function payNotify() { $response = $this->app->handlePaidNotify(function ($message, $fail) { $pay_common = new PayCommon(); if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态 if ($message['result_code'] === 'SUCCESS') { // 判断支付金额是否等于支付单据的金额 $pay_info = $pay_common->getPayInfo($message['out_trade_no'])['data']; if (empty($pay_info)) return $fail('通信失败,请稍后再通知我'); if ($message['total_fee'] != round($pay_info['pay_money'] * 100)) return; // 用户是否支付成功 $pay_common->onlinePay($message['out_trade_no'], "wechatpay", $message["transaction_id"], "wechatpay"); } } else { return $fail('通信失败,请稍后再通知我'); } return true; }); $response->send(); return $response; } /** * 关闭支付单据 * @param array $param * @return array * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \GuzzleHttp\Exception\GuzzleException */ public function payClose(array $param) { $result = $this->app->order->close($param["out_trade_no"]); if ($result["return_code"] == 'FAIL') { return $this->error([], $result["return_msg"]); } if ($result["result_code"] == 'FAIL') { if ($result['err_code'] == 'ORDERPAID') return $this->error(['is_paid' => 1, 'pay_type' => 'wechatpay'], $result['err_code_des']); return $this->error([], $result['err_code_des']); } return $this->success(); } /** * 申请退款 * @param array $param */ public function refund(array $param) { $pay_info = $param["pay_info"]; $refund_no = $param["refund_no"]; $total_fee = round($pay_info["pay_money"] * 100); $refund_fee = round($param["refund_fee"] * 100); $result = $this->app->refund->byOutTradeNumber($pay_info["out_trade_no"], $refund_no, $total_fee, $refund_fee, []); //调用失败 if ($result["return_code"] == 'FAIL') return $this->error([], $result["return_msg"]); if ($result["result_code"] == 'FAIL') return $this->error([], $result["err_code_des"]); return $this->success(); } /** * 转账 * @param array $param * @return array\ */ public function transfer(array $param) { $data = [ 'partner_trade_no' => $param['out_trade_no'], // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号) 'openid' => $param['account_number'], 'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名 're_user_name' => $param['real_name'], // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名 'amount' => $param['amount'] * 100, // 转账金额 'desc' => $param['desc'] ]; $res = $this->app->transfer->toBalance($data); if ($res['return_code'] == 'SUCCESS') { if ($res['result_code'] == 'SUCCESS') { return $this->success([ 'out_trade_no' => $res['partner_trade_no'], // 商户交易号 'payment_no' => $res['payment_no'], // 微信付款单号 'payment_time' => $res['payment_time'] // 付款成功时间 ]); } else { return $this->error([], $res['err_code_des']); } } else { return $this->error([], $res['return_msg']); } } /** * 付款码支付 * @param array $param * @return array\ */ public function micropay(array $param){ $data = [ 'body' => str_sub($param["pay_body"], 15), 'out_trade_no' => $param["out_trade_no"], 'total_fee' => $param["pay_money"] * 100, 'auth_code' => $param["auth_code"] ]; $result = $this->app->base->pay($data); if ($result[ 'return_code' ] == 'FAIL') { return $this->error([], $result[ 'return_msg' ]); } if ($result[ 'result_code' ] == 'FAIL') { return $this->error([], $result[ 'err_code_des' ]); } return $this->success($result); } }