site_id = $site_id; $config_model = new Config(); $config_result = $config_model->getPayConfig($site_id); $config = $config_result["data"]['value']; $this->config = $config; $this->aop = new AopClient(); if ($this->config['is_isp'] == 1) { $this->aop->is_isp = 1; $this->aop->gatewayUrl = 'https://pay.chanpay.com/merchant/gateway'; } else { $this->aop->publicKey = $config_info['public_key'] ?? ""; //应用公钥 $this->aop->cjRsaPublicKey = $config_info['cj_public_key'] ?? ""; $this->aop->rsaPrivateKey = $config_info['private_key'] ?? ""; //应用私钥 $this->aop->gatewayUrl = 'https://pay.chanpay.com/ugtw/gateway'; } $this->aop->apiVersion = '1.0'; $this->aop->signType = 'RSA2'; $this->aop->postCharset = 'UTF-8'; $this->aop->format = 'JSON'; } catch (\Exception $e) { exit(json_encode($this->error('', '配置错误'))); } } // 根据支付类型 获取对应的支付参数 // 根据支付类型 获取对应的支付参数 public function pay($params) { //构造要请求的参数数组,无需改动 $outTradeNo = $params['out_trade_no'] ?? ''; $parameter = array( 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $outTradeNo, "body" => str_sub($params["pay_body"], 60), "attach" => $outTradeNo, 'total_amount' => (int)sprintf("%.0f", $params['pay_money'] * 100), 'mch_create_ip' => request()->ip() ); $mch_info = $params['mch_info']; if ($mch_info) { $mch_info = json_decode($mch_info, true); if (isset($mch_info['proxy_pay']) && $mch_info['proxy_pay'] == 1) { $parameter['merchant_id'] = $mch_info['mch_id']; } } $attach = [ 'out_trade_no' => $outTradeNo, 'endDivide' => 0, ]; $res = event('checkAccountsAuth', ['site_id' => $this->site_id, 'pay_type' => 'cypay', 'out_trade_no' => $params["out_trade_no"]], true); if ($res && $res['isDivide']) { $attach['endDivide'] = 0; } else { $attach['endDivide'] = 1; } $parameter['attach'] = json_encode($attach); if ($params["pay_type"] == 'cywechatpay') { if ($params["app_type"] == 'h5' || $params["app_type"] == 'wechat') { $wechat_config = (new WechatConfig())->getWechatConfig($this->site_id)['data']['value']; $this->config['app_id'] = $wechat_config['appid'] ?? ''; } else { $weapp_config = (new WeappConfig())->getWeappConfig($this->site_id)['data']['value']; $this->config['app_id'] = $weapp_config['appid'] ?? ''; } } else if ($params["pay_type"] == 'cyalipay') { } try { switch ($params["app_type"]) { case "pc": case 'cashier': case "h5": $request = new TradeWapPayRequest(); $request->setMethodName('chanpay.merchanttrade.aggregate.precreate'); $request->setFunctionCode('1000110001'); break; case "app": break; // 微信小程序支付 case 'weapp': $parameter['sub_openid'] = model('member')->getValue(['member_id' => $params['member_id']], 'weapp_openid'); $request = new TradeCreateRequest(); if ($this->config['is_cashier'] == 1) { $request->setMethodName('chanpay.merchanttrade.appletpay.cashier'); $request->setFunctionCode('1000160001'); } else { $request->setFunctionCode($params["trade_type"]); } break; case 'wechat': $parameter['sub_appid'] = $this->config['app_id']; $parameter['sub_openid'] = model('member')->getValue(['member_id' => $params['member_id']], 'wx_openid'); $request = new TradeWapPayRequest(); $request->setMethodName('chanpay.merchanttrade.weixin.jspay'); $request->setFunctionCode('1000120004'); break; case "aliapp": $request = new TradeWapPayRequest(); $request->setMethodName('chanpay.merchanttrade.alipay.jspay'); $request->setFunctionCode('1000120002'); break; } if ($this->config['is_cashier'] == 1) { $parameter['notify_url'] = $params["notify_url"]; unset($parameter['mch_create_ip']); $paydata = base64_encode(json_encode($parameter)); $path = urlencode('/pages_tool/pay/result?code=' . $outTradeNo); $data = [ "pay_type" => $params["pay_type"], 'is_cashier' => 1, 'appId' => $this->config['app_id'], "cashier" => "jsapi", "cashier_appid" => "wx1eac96cd7bac0ade", "envVersion" => "release",//开发develop ,测试trial,正式release "path" => "pages/pay/mp?paydata={$paydata}&appId={$this->config['app_id']}&path={$path}", ]; return $this->success($data); } $request->setBizContent($parameter); $request->SetNotifyUrl($params["notify_url"]); $result = $this->aop->execute($request); $resultCode = $result['code']; if (!empty($resultCode) && $resultCode == 0000) { if ($params["app_type"] == 'cashier') { return $this->success([ 'type' => 'qrcode', 'data' => [ // 'qrcode' => $result->$responseNode->qr_code ] ]); } $data = []; if ($params["app_type"] == 'weapp' && $this->config['is_cashier'] == 1) { $result['content']['is_cashier'] = 1; $data = $result['content']; } if ($params["app_type"] == 'h5' || $params["app_type"] == 'wechat') { $data = [ "type" => "jsapi", "data" => json_decode($result['content']['pay_info'], true) ]; } return $this->success($data); } else { return $this->error("", $result['sub_msg']); } return $result; } catch (\Exception $e) { return $this->error("", $e->getMessage()); } } /** * 支付关闭 * @param unknown $orderNumber * @return multitype:number string |multitype:number mixed */ public function close($param) { $parameter = array( "out_trade_no" => $param["pay_no"] ); // 建立请求 $request = new TradeCloseRequest(); $request->setBizContent(json_encode($parameter)); $request->setFunctionCode($param['pay_addon']); $result = $this->aop->execute($request); $resultCode = $result['code']; if (!empty($resultCode) && $resultCode == 0000) { return $this->success(); } else { return $this->error("", $result['sub_msg']); } return $this->success(); } /** * 支付宝支付原路返回 * @param unknown $param 支付参数 */ public function refund($param) { $pay_info = $param["pay_info"]; $refund_no = $param["refund_no"]; $out_trade_no = $pay_info["pay_no"] ?? ''; $refund_fee = $param["refund_fee"]; $parameter = array( 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $out_trade_no, 'total_amount' => $pay_info['pay_money'] * 100, 'refund_amount' => $refund_fee * 100, 'out_refund_no' => $refund_no ); if ($param["refund_desc"]) { $parameter['refund_desc'] = $$param["refund_desc"]; } // 建立请求 $request = new TradeRefundRequest(); $request->setBizContent(json_encode($parameter)); $request->setFunctionCode($pay_info['pay_addon']); $result = $this->aop->execute($request); $resultCode = $result['code']; if (!empty($resultCode) && $resultCode == 0000) { return $this->success(); } else { return $this->error($pay_info["pay_type"], $result['sub_msg']); } } // 支付异步通知处理 public function payNotify($param) { try { $res = $this->aop->rsaCheckV1(request()->post()); if ($res) { // 验证成功 $bizContent = $this->aop->rsaDecrypt($param['biz_content']); $outTradeNo = substr($bizContent['out_trade_no'], 0, -3); $payInfo = (new PayCommon())->getPayInfo($outTradeNo); $payInfo = $payInfo['data'] ?? null; $pay_result = $bizContent['pay_result']; if (empty($payInfo)) { $returnData = ['return_code' => 'FAIL', 'return_msg' => '订单不存在']; } else if ($pay_result == 0) { $pay_no = $bizContent['out_trade_no']; $pay_voucher = $bizContent['chanpay_trade_no']; $attach = json_decode($bizContent['attach'], true); $josn = json_encode([ 'attach' => $attach, 'pay_result' => $pay_result, 'channel_transaction_id' => $bizContent['channel_transaction_id'], 'trade_type' => $bizContent['trade_type'], ]); (new PayCommon())->onlinePay($outTradeNo, $param['paytype'], $bizContent['transaction_id'], $param['function_code'], [], $pay_no, $pay_voucher, $josn); $returnData = ['return_code' => 'SUCCESS', 'return_msg' => 'OK']; if (empty($attach) || (!empty($attach['endDivide']) && $attach['endDivide'] == 1)) { $this->profitsharingFinish($pay_no, $outTradeNo); //解除分账 } } else { $returnData = ['return_code' => 'FAIL', 'return_msg' => '支付失败']; } } } catch (\Exception $e) { $returnData = ['return_code' => 'FAIL', 'return_msg' => $e->getMessage()]; } // 验签失败 or 处理失败 echo json_encode($returnData, JSON_UNESCAPED_UNICODE); } /*** * 绑定分账收款账号 * @param $out_order_no * @param $receiver_list * @return array * @throws \Exception */ public function relationBindAccounts($out_order_no, $receiver_list) { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_order_no' => $out_order_no, 'receiver_list' => $receiver_list, ]; $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $result = $this->aop->execute($request); $resultCode = $result['code']; $sub_msg = $result['sub_msg']; if (!empty($resultCode) && $resultCode == 0000 && strpos($sub_msg, '绑定关系已存在') !== false) { return $this->success(); } else { return $this->error('', $result['sub_msg']); } } /*** * 分账查询 * @param $out_order_no * @return array * @throws \Exception */ public function relationQuery($out_order_no) { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_order_no' => $out_order_no, ]; $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchant.profitsharing.relation.query'); $result = $this->aop->execute($request); return $result; } /*** * 提交分账 * @param $out_order_no 商家订单号 * @param $out_order_id 请求编号 * @param $trans_out_amount 分账金额 * @param $receiver_list 分账列表 * @return array * @throws \Exception */ public function profitsharing($out_order_no, $out_order_id, $receiver_list, $unfreeze_unsplit = true) { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $out_order_no, 'out_order_no' => $out_order_id, 'trans_out_amount' => array_sum(array_column($receiver_list, 'amount')), 'royalty_parameters' => $receiver_list, ]; $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchanttrade.profitsharing'); $result = $this->aop->execute($request); $resultCode = $result['code']; if (!empty($resultCode) && $resultCode == 0000) { $content = $result['content']; $trade_state = $content['trade_state']; if ($trade_state == 'FINISHED') { if ($unfreeze_unsplit) { $this->profitsharingFinish($out_order_no, $out_order_id); } return $this->success(); } else { return $this->error('', $content['trade_state_desc']); } } else { if ($result['sub_msg'] == '该订单已分账') { return $this->success(); } else { return $this->error('', $result['sub_msg']); } } } /*** * 标记分账完成 * @param $out_order_no * @param $out_order_id * @param $description * @return array * @throws \Exception */ public function profitsharingFinish($out_order_no, $out_order_id, $description = '') { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $out_order_no, 'out_order_no' => $out_order_id ]; if ($description) { $parameter['description'] = $description; } $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchanttrade.profitsharing.finish'); $result = $this->aop->execute($request); $resultCode = $result['code']; if (!empty($resultCode) && $resultCode == 0000) { return $this->success(); } else { return $this->error('', $result['sub_msg']); } } /*** * 分账查询 * @param $out_order_no * @param $out_order_id * @return mixed|string * @throws \Exception */ public function profitsharingQuery($out_order_no, $out_order_id) { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $out_order_no, 'out_order_no' => $out_order_id ]; $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchanttrade.profitsharing.query'); $result = $this->aop->execute($request); return $result; } /*** * 发起回退 * @param $out_order_no * @param $out_return_no * @param $out_order_id * @param $return_account * @param $description * @return array * @throws \Exception */ public function profitsharingReturn($out_order_no, $out_return_no, $out_order_id, $return_account, $description = '') { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_return_no' => $out_return_no, 'out_order_no' => $out_order_id, 'return_account' => $return_account, 'description' => '分账回退', ]; if ($description) { $parameter['description'] = $description; } $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchanttrade.profitsharing.return'); $result = $this->aop->execute($request); if (!empty($resultCode) && $resultCode == 0000) { return $this->success(); } else { return $this->error('', $result['sub_msg']); } } /*** * 查询回退 * @param $out_order_no * @param $out_order_id * @return mixed|string * @throws \Exception */ public function profitsharingReturnQuery($out_order_no, $out_order_id) { $request = new TradeBingAccountsRequest(); $parameter = [ 'merchant_id' => $this->config['mch_id'], 'out_trade_no' => $out_order_no, 'out_order_no' => $out_order_id ]; $request->setBizContent(json_encode($parameter)); $request->setFunctionCode('1000100001'); $request->setMethodName('chanpay.merchanttrade.profitsharing.return.query'); $result = $this->aop->execute($request); return $result; } }