find(); $config = [ 'app_id' => isset($info['routine_appid']) ? trim($info['routine_appid']) : '', 'secret' => isset($info['routine_appsecret']) ? trim($info['routine_appsecret']) : '', 'token' => isset($info['wechat_token']) ? trim($info['wechat_token']) : '', 'aes_key' => isset($info['wechat_encodingaeskey']) ? trim($info['wechat_encodingaeskey']) : '' ]; if (isset($info['pay_routine_open']) && $info['pay_routine_open'] == 1) { $config1 = [ 'merchant_id' => trim($info['pay_routine_mchid']), 'key' => trim($info['pay_routine_key']), 'cert_path' => realpath('.' . $info['pay_routine_client_cert']), 'key_path' => realpath('.' . $info['pay_routine_client_key']), 'notify_url' => Request::instance()->domain(). "/api/routine/notify/".$cid ]; $config = array_merge($config,$config1); } return $config; } public static function miniprogram($cache = false,$cid) { (self::$instance['cid'] === null || $cache === true) && (self::$instance['cid'] = Factory::miniProgram(self::options($cid))); return self::$instance['cid']; } /** * 支付接口 * @param false $cache * @param int $cid * @return \EasyWeChat\Payment\Application|mixed */ public static function payment($cache = false,$cid=0) { (self::$app[$cid] === null || $cache === true) && (self::$app[$cid] = Factory::payment(self::options($cid))); return self::$app[$cid]; } /** * 获得用户信息 根据code 获取session_key * @param array|string $openid * @return $userInfo */ public static function getUserInfo($cid,$code) { $userInfo = self::miniprogram(false,$cid)->auth->session($code); return $userInfo; } /** * 加密数据解密 * @param $sessionKey * @param $iv * @param $encryptData * @return $userInfo */ public static function encryptor($cid,$sessionKey, $iv, $encryptData) { return self::miniprogram(false,$cid)->encryptor->decryptData($sessionKey, $iv, $encryptData); } /** * 订阅模板消息接口 * @return \crmeb\services\subscribe\ProgramSubscribe */ public static function SubscribenoticeService($cid) { return self::miniprogram(false,$cid)->subscribe_message; } /** * 发送订阅消息 * @param string $touser 接收者(用户)的 openid * @param string $templateId 所需下发的订阅模板id * @param array $data 模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } } * @param string $link 击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 * @return \EasyWeChat\Support\Collection|null * @throws \EasyWeChat\Core\Exceptions\HttpException * @throws \EasyWeChat\Core\Exceptions\InvalidArgumentException */ public static function sendSubscribeTemlate($cid,string $touser, string $templateId, array $data, string $link = '') { $msg = [ 'template_id' => $templateId, // 所需下发的订阅模板id 'touser' => $touser, // 接收者(用户)的 openid 'page' => $link, // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转。 'data' => $data, ]; return self::SubscribenoticeService($cid)->send($msg); } /** * 生成支付订单对象 * @param $openid * @param $out_trade_no * @param $total_fee * @param $attach * @param $body * @param string $detail * @param string $trade_type * @param array $options * @return Order */ public static function paymentOrder($openid, $out_trade_no, $total_fee, $attach, $body, $detail = '', $trade_type = 'JSAPI', $options = [],$cid=0) { $total_fee = bcmul($total_fee, 100, 0); $order = array_merge(compact('out_trade_no', 'total_fee', 'attach', 'body', 'detail', 'trade_type'), $options); // if (!is_null($openid)) $order['openid'] = $openid; if ($order['detail'] == '') unset($order['detail']); $result = self::payment(false,$cid)->order->unify($order); return $result; } /** * 使用商户订单号退款 * @param $orderNo * @param $opt */ public static function payOrderRefund($cid,$orderNo, array $opt) { if (!isset($opt['pay_price'])) exception('缺少pay_price'); $totalFee = floatval(bcmul($opt['pay_price'], 100, 0)); $refundFee = isset($opt['refund_price']) ? floatval(bcmul($opt['refund_price'], 100, 0)) : null; $refundReason = isset($opt['desc']) ? $opt['desc'] : ''; $refundNo = isset($opt['refund_id']) ? $opt['refund_id'] : $orderNo; $opUserId = isset($opt['op_user_id']) ? $opt['op_user_id'] : null; $type = isset($opt['type']) ? $opt['type'] : 'out_trade_no'; /*仅针对老资金流商户使用 REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款) REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款*/ $refundAccount = isset($opt['refund_account']) ? $opt['refund_account'] : 'REFUND_SOURCE_UNSETTLED_FUNDS'; try { $res = self::payment('false',$cid)->byOutTradeNumber($orderNo,$refundNo,$totalFee,$refundFee,['refund_desc'=>$refundReason]); if ($res->return_code == 'FAIL') exception('退款失败:' . $res->return_msg); if (isset($res->err_code)) exception('退款失败:' . $res->err_code_des); } catch (\Exception $e) { exception($e->getMessage()); } return true; } /** * 微信支付成功回调接口 */ public static function handleNotify($cid) { $response = self::payment(true,$cid)->handlePaidNotify(function ($notify, $successful) use($cid){ if ($successful && isset($notify['out_trade_no'])) { if (isset($notify['attach']) && $notify['attach']) { if (($count = strpos($notify['out_trade_no'], '_')) !== false) { $notify['out_trade_no'] = substr($notify['out_trade_no'], $count + 1); } $params = [$cid,$notify['out_trade_no']]; Hook::exec("\\liuniu\\repositories\\PaymentRepositories","wechat".ucfirst($notify['attach']),$params); } $data = ['eventkey' => 'notify', 'command' => '', 'refreshtime' => time(), 'openid' => $notify['openid'],'message'=>json_encode($notify)]; $wechatContext = WechatContext::create($data, true); return true; } }); $response->send(); } public static function getToken($cid) { $token = self::miniprogram(false,$cid)->access_token->getToken(); return $token; } /** * 生成支付签约订单对象 * @param $openid * @param $out_trade_no * @param $total_fee * @param $attach * @param $body * @param string $detail * @param string $trade_type * @param array $options * @return Order */ public static function paysignedOrder($openid, $out_trade_no, $total_fee, $attach, $body,$contract_code,$plan_id,$spbill_create_ip, $detail = '', $trade_type = 'JSAPI', $options = [],$cid=0,$contract_display_account='',$contract_notify_url='') { $total_fee = bcmul($total_fee, 100, 0); $order = array_merge(compact('out_trade_no', 'total_fee', 'attach', 'body', 'detail', 'trade_type','contract_code','spbill_create_ip','plan_id','contract_display_account','contract_notify_url'), $options); if (!is_null($openid)) $order['openid'] = $openid; if ($order['detail'] == '') unset($order['detail']); $result = self::payment(false,$cid)->order->unify($order,true); return $result; } }