basePath . "/utils/Adapay/bspay-php-sdk/BsPaySdk"); include_once BsPaySdk_Path . "/init.php"; class AdapayV2 extends Adapay { public static $notify_url = 'adapay/notify'; public static $h5_url = 'adapay/h5'; public static $confs = []; public static function verifySign($store_id, $resp_sign, $resp_data) { $conf = self::conf($store_id); # 对返回数据验签失败的逻辑分支 if (!BsPayTools::verifySign($resp_sign, $resp_data, $conf['v2']['rsa_huifu_public_key'])) { debug_log([__METHOD__, __LINE__, $resp_sign, $resp_data], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '接口结果返回签名验证失败', ]; } return [ 'code' => 0, 'msg' => 'ok', ]; } public static function initRequest($class) { include_once BsPaySdk_Path . "/request/" . $class . ".php"; $className = 'BsPaySdk\\request\\' . $class; $obj = new $className(); return $obj; } public static function initStoreAdapay($store_id) { $conf = self::conf($store_id); BsPay::init($conf['v2'], true); } public static function create($pay_type, $order, $type, $goods_names = null, $total_pay_price = 0, $is_app = false, $balance_price = 0, $is_h5 = false, $is_official = false) { $store_id = $order->store_id; self::initStoreAdapay($store_id); $param = self::paymentParams($pay_type, $order, $type, $goods_names, $total_pay_price, $is_app, $balance_price, $is_h5, $is_official); # 创建请求Client对象,调用接口 $client = new BsPayClient(); $result = $client->postRequest($param); $httpStateCode = $result->getHttpStateCode(); if($httpStateCode != 200){ // debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => $httpStateCode, 'msg' => '操作失败,HTTP_STATE_CODE-' . $httpStateCode . '。参考:https://paas.huifu.com/partners/api/#/csfl/api_csfl_ywm?id=网关返回码', ]; } $data = $result->getRspDatas(); // var_dump($result);die; if (!$result || $result->isError()) { //失败处理 debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '操作失败,' . $result -> getErrorInfo()['msg'], 'res' => $data, ]; } if($data['data']['resp_code'] > 100){ debug_log([__METHOD__, __LINE__, $data], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '操作失败,' . $data['data']['resp_code'] . ',' . $data['data']['resp_desc'], 'res' => $data, ]; } if($data['data']['trans_stat'] === 'F'){ return [ 'code' => 1, 'msg' => '操作失败,adapay交易失败', 'res' => $data, ]; } $return = [ 'code' => 0, 'msg' => '操作成功', 'data' => $data, 'res' => $data, 'body' => $goods_names, '$param' => $param, ]; if(!empty($data['data']['pay_info'])){ $return['data'] = json_decode($data['data']['pay_info'], true); } if ($type == OrderNo::ORDER_UNION) { foreach ($order as $value) { $value->order_union_id = $value->id; $value->adapay_payment_id = $data['data']['hf_seq_id']; $value->save(); } $return['order_no'] = $data['data']['req_seq_id']; $return['body'] = $data['data']['goods_desc']; }else{ $order->adapay_payment_id = $data['data']['hf_seq_id']; $order->save(); } debug_log([$data, $return, $order->getFirstErrors()], __CLASS__ . '.log'); if ($is_h5) { $return['res']['mweb_url'] = $return['res']['mweb_url'] . '&redirect_url=' . \Yii::$app->request->hostInfo . '/h5/#/order/order/order'; } return $return; } public static function params_notify_url($data) { $data['params']['notify_url'] = pay_notify_url(self::$notify_url); return $data; } public static function params_huifu_id($data, $store_id) { $conf = self::conf($store_id)['v2']; $data['params']['huifu_id'] = $conf['huifu_id']; return $data; } public static function params_risk_check_data($data) { $ip_addr = \Yii::$app->request->remoteIP; $data['params']['risk_check_data'] = self::json_encode([ 'ip_addr' => $ip_addr, ]); return $data; } public static function params_terminal_device_data($data) { $ip_addr = \Yii::$app->request->remoteIP; $data['params']['terminal_device_data'] = self::json_encode([ 'device_type' => 1, 'device_ip' => $ip_addr, ]); return $data; } public static function json_encode($param) { return json_encode($param,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); } public static function req_seq_id2order_no($req_seq_id){ if(strstr($req_seq_id, '_')){ return explode('_', $req_seq_id)[0]; } return $req_seq_id; } public static function order_no2req_seq_id($order_no){ return $order_no . '_' . time(); } public static function paymentParams($pay_type, $order, $type, $goods_names, $total_pay_price, $is_app, $balance_price, $is_h5, $is_official) { $param = []; $ip_addr = \Yii::$app->request->remoteIP; $store_id = $order->store_id; $user_id = $order->user_id; $user = \app\models\User::findOne($user_id); if ($type == OrderNo::ORDER_UNION) { $goods_title = count($order) . '笔订单合并支付'; $out_trade_no = OrderNo::getOrderNo(OrderNo::ORDER_UNION); $total_fee = $balance_price > 0 ? floatval($total_pay_price - $balance_price) * 100 : $total_pay_price * 100; $order_union = new OrderUnion(); $order_union->store_id = $store_id; $order_union->user_id = $user_id; $order_union->order_no = $out_trade_no; $order_union->price = $total_pay_price; $order_union->is_pay = 0; $order_union->created_at = time(); $order_union->is_delete = 0; $order_id_list = []; foreach ($order as $value) { $order_id_list[] = $value->id; } $order_union->order_id_list = json_encode($order_id_list); if (!$order_union->save()) { foreach ($order_union->errors as $error) { return [ 'code' => 1, 'msg' => $error ]; } } } else { $pay_price = $order->pay_price; // if ($type != OrderNo::ORDER_RECHARGE) { // if (isset($order->is_delivery) && $order->is_delivery == 1) { // $deliveryInfo = DeliveryInfo::find()->where(['order_no' => $order->order_no])->one(); // if ($deliveryInfo) { // $pay_price += $deliveryInfo->fee; // } // } // } $goods_title = mb_substr($goods_names, 0, 20); $out_trade_no = $order->order_no; $total_fee = $balance_price > 0 ? floatval($pay_price - $balance_price) * 100 : $pay_price * 100; } if($pay_type == Order::PAY_TYPE_ADAPAY_QUICKPAY_FRONTPAY){ // new \BsPaySdk\request\V2TradeOnlinepaymentQuickpayFrontpayRequest; $request = self::initRequest('V2TradeOnlinepaymentQuickpayFrontpayRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => self::order_no2req_seq_id($out_trade_no), "req_date" => date("Ymd"), "goods_desc" => $goods_title, // "huifu_id" => $conf['huifu_id'], "user_huifu_id" => $user->adapay_user_huifu_id, "trans_amt" => sprintf("%.2f", $total_fee/100), 'request_type' => 'M', // 'notify_url' => pay_notify_url(self::$notify_url), 'front_url' => pay_notify_url(self::$h5_url), 'extend_pay_data' => self::json_encode([ 'goods_short_name' => '1', 'biz_tp' => '100099', 'gw_chnnl_tp' => '02', ]), ), ); $param = self::params_huifu_id($param, $store_id); $param = self::params_risk_check_data($param); $param = self::params_terminal_device_data($param); $param = self::params_notify_url($param); } if($pay_type == Order::PAY_TYPE_HUIFU_V2_JSPAY_WX){ if ($is_app) { $open_id = get_user()->wechat_app_open_id; } else if ($is_official) { $open_id = get_user()->wechat_platform_open_id; } else { $open_id = get_user()->wechat_open_id; } $from_type = WechatConfig::TYPE_CONFIG_MINI; $store_wechat = WechatConfig::findOne(['store_id' => get_store_id(), 'type' => $from_type]); $sub_appid = $store_wechat->app_id; // new \BsPaySdk\request\V2TradePaymentJspayRequest(); $request = self::initRequest('V2TradePaymentJspayRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => self::order_no2req_seq_id($out_trade_no), "req_date" => date("Ymd"), "goods_desc" => $goods_title, 'trade_type' => 'T_JSAPI', // "huifu_id" => $conf['huifu_id'], "trans_amt" => sprintf("%.2f", $total_fee/100), // 'notify_url' => pay_notify_url(self::$notify_url), 'wx_data' => [ 'sub_appid' => $sub_appid, 'sub_openid' => $open_id, ], ), ); $param = self::params_huifu_id($param, $store_id); $param = self::params_risk_check_data($param); $param = self::params_terminal_device_data($param); $param = self::params_notify_url($param); } return $param; } /** * 退款 * @param Object $order * @param string $orderRefundNo * @param string $type * @param integer $refundFee * @param $refund_account * @return array */ public static function orderRefund($order, $type, $refundFee, $orderRefundNo, $refund_account = null, $profit_share = 1) { $store_id = $order->store_id; self::initStoreAdapay($store_id); // new \BsPaySdk\request\V2TradeOnlinepaymentRefundRequest; $request = self::initRequest('V2TradeOnlinepaymentRefundRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => self::order_no2req_seq_id($order->order_no) . '_refund', "req_date" => date("Ymd") -1, "ord_amt" => sprintf("%.2f", $order->pay_price), 'org_hf_seq_id' => $order->adapay_payment_id, // 'org_req_seq_id' => $order->order_no, // 'org_req_date' => date("Ymd") -1, ), ); if($order->pay_type == Order::PAY_TYPE_HUIFU_V2_JSPAY_WX){ // new \BsPaySdk\request\V2TradePaymentScanpayRefundRequest; $request = self::initRequest('V2TradePaymentScanpayRefundRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => self::order_no2req_seq_id($order->order_no) . '_refund', "req_date" => date("Ymd"), "ord_amt" => sprintf("%.2f", $order->pay_price), 'org_hf_seq_id' => $order->adapay_payment_id, // 'org_req_seq_id' => $order->order_no, 'org_req_date' => date("Ymd", $order->pay_time), ), ); } $param = self::params_huifu_id($param, $store_id); $param = self::params_risk_check_data($param); $param = self::params_terminal_device_data($param); $param = self::params_notify_url($param); # 创建请求Client对象,调用接口 $client = new BsPayClient(); $result = $client->postRequest($param); $httpStateCode = $result->getHttpStateCode(); if($httpStateCode != 200){ // debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => $httpStateCode, 'msg' => '操作失败,HTTP_STATE_CODE-' . $httpStateCode . '。参考:https://paas.huifu.com/partners/api/#/csfl/api_csfl_ywm?id=网关返回码', ]; } $data = $result->getRspDatas(); // var_dump($result);die; if (!$result || $result->isError()) { //失败处理 debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '退款失败1,' . $result -> getErrorInfo()['msg'], 'res' => $data, ]; } if($data['data']['resp_code'] > 100){ debug_log([__METHOD__, __LINE__, $data], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '退款失败2,错误码:' . $data['data']['resp_code'] . ',' . $data['data']['resp_desc'], 'res' => $data, ]; } if($data['data']['trans_stat'] == 'F'){ return [ 'code' => 1, 'msg' => '操作失败,adapay交易失败', 'res' => $data, ]; } $return = [ 'code' => 0, 'msg' => '操作成功', 'data' => $data, ]; if($data['data']['trans_stat'] == 'P'){ $return = [ 'code' => 0, 'msg' => '处理中,银行受理结果:' . $data['data']['bank_code'] . $data['data']['bank_message'] . '。', 'res' => $data, ]; } // 联合支付,退余额 if ($order->is_combine_pay == 1 && $order->combine_money > 0) { AccountLog::saveLog($order->user_id, $order->combine_money, AccountLog::TYPE_BALANCE, AccountLog::LOG_TYPE_INCOME, AccountLog::TYPE_PLATFORM_REFUND_ORDER, $order->id, "商城订单退款,订单号:{$order->order_no}"); } return $return; } public static function merchant_busi_config_query($store_id) { self::initStoreAdapay($store_id); // new \BsPaySdk\request\V2MerchantBusiConfigQueryRequest(); $request = self::initRequest('V2MerchantBusiConfigQueryRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => time() . '_merchant', "req_date" => date("Ymd"), ), ); $param = self::params_huifu_id($param, $store_id); # 创建请求Client对象,调用接口 $client = new BsPayClient(); $result = $client->postRequest($param); $httpStateCode = $result->getHttpStateCode(); if($httpStateCode != 200){ // debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => $httpStateCode, 'msg' => '操作失败,HTTP_STATE_CODE-' . $httpStateCode . '。参考:https://paas.huifu.com/partners/api/#/csfl/api_csfl_ywm?id=网关返回码', ]; } $data = $result->getRspDatas(); // var_dump($result);die; if (!$result || $result->isError()) { //失败处理 debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '失败1,' . $result -> getErrorInfo()['msg'], 'res' => $data, ]; } $return = [ 'code' => 0, 'msg' => '操作成功', 'data' => $data, 'url_fee_type' => 'https://paas.huifu.com/open/doc/api/#/api_ggcsbm?id=%e5%be%ae%e4%bf%a1%e4%b8%9a%e5%8a%a1%e5%bc%80%e9%80%9a%e7%b1%bb%e5%9e%8b', 'url_config' => 'https://paas.huifu.com/open/doc/api/#/shgl/shjj/api_shjj_wxshpz', ]; return $return; } public static function merchant_busi_config($store_id, $conf) { self::initStoreAdapay($store_id); // new \BsPaySdk\request\V2MerchantBusiConfigRequest(); $request = self::initRequest('V2MerchantBusiConfigRequest'); $param = array( "funcCode" => $request->getFunctionCode(), "params" => array( "req_seq_id" => time() . '_merchantConf', "req_date" => date("Ymd"), // 'fee_type' => '02', // 'wx_applet_app_id' => 'wxac56e7dc6301d517', ), ); $param['params'] = array_merge($param['params'], $conf); $param = self::params_huifu_id($param, $store_id); # 创建请求Client对象,调用接口 $client = new BsPayClient(); $result = $client->postRequest($param); $httpStateCode = $result->getHttpStateCode(); if($httpStateCode != 200){ // debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => $httpStateCode, 'msg' => '操作失败,HTTP_STATE_CODE-' . $httpStateCode . '。参考:https://paas.huifu.com/partners/api/#/csfl/api_csfl_ywm?id=网关返回码', ]; } $data = $result->getRspDatas(); // var_dump($result);die; if (!$result || $result->isError()) { //失败处理 debug_log([__METHOD__, __LINE__, $result->getErrorInfo()], __CLASS__ . '.log'); return [ 'code' => 1, 'msg' => '失败1,' . $result -> getErrorInfo()['msg'], 'res' => $data, ]; } $return = [ 'code' => 0, 'msg' => '操作成功', 'data' => $data, ]; return $return; } }