123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <?php
- namespace liuniu;
- use app\admin\model\Company;
- use app\common\model\WechatContext;
- use EasyWeChat\Factory;
- use think\Hook;
- use think\Request;
- class MiniProgramService
- {
- private static $instance = null;
- private static $app = null;
- public static function options($cid)
- {
- $info = Company::where('id',$cid)->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;
- }
- }
|