CRMEB/application/core/util/MiniProgramService.php
2019-05-16 14:28:37 +08:00

314 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
*
* @author: xaboy<365615158@qq.com>
* @day: 2017/11/23
*/
namespace app\core\util;
use app\core\behavior\PaymentBehavior;
use EasyWeChat\Foundation\Application;
use EasyWeChat\Payment\Order;
use think\Url;
use service\HookService;
use app\core\implement\ProviderInterface;
/**微信小程序接口
* Class WechatMinService
* @package service
*/
class MiniProgramService implements ProviderInterface
{
private static $instance = null;
public function register($config)
{
return ['mini_program',new self()];
}
public static function options()
{
$wechat = SystemConfigService::more(['site_url','routine_appId','routine_appsecret']);
$payment = SystemConfigService::more(['pay_routine_mchid','pay_routine_key','pay_routine_client_cert','pay_routine_client_key','pay_weixin_open']);
$config = [];
$config['mini_program'] = [
'app_id'=>isset($wechat['routine_appId']) ? $wechat['routine_appId']:'',
'secret'=>isset($wechat['routine_appsecret']) ? $wechat['routine_appsecret']:'',
'token'=>isset($wechat['wechat_token']) ? $wechat['wechat_token']:'',
'aes_key'=> isset($wechat['wechat_encodingaeskey']) ? $wechat['wechat_encodingaeskey']:''
];
if(isset($payment['pay_weixin_open']) && $payment['pay_weixin_open'] == 1){
$config['payment'] = [
'app_id'=>isset($wechat['routine_appId']) ? $wechat['routine_appId']:'',
'merchant_id'=>$payment['pay_routine_mchid'],
'key'=>$payment['pay_routine_key'],
'cert_path'=>realpath('.'.$payment['pay_routine_client_cert']),
'key_path'=>realpath('.'.$payment['pay_routine_client_key']),
'notify_url'=>$wechat['site_url'].Url::build('/ebapi/notify/notify',['notify_type'=>'routine'])
];
}
return $config;
}
public static function application($cache = false)
{
(self::$instance === null || $cache === true) && (self::$instance = new Application(self::options()));
return self::$instance;
}
/**
* 小程序接口
* @return \EasyWeChat\MiniProgram\MiniProgram
*/
public static function miniprogram()
{
return self::application()->mini_program;
}
/**
* 获得用户信息 根据code 获取session_key
* @param array|string $openid
* @return $userInfo
*/
public static function getUserInfo($code)
{
$userInfo = self::miniprogram()->sns->getSessionKey($code);
return $userInfo;
}
/**
* 加密数据解密
* @param $sessionKey
* @param $iv
* @param $encryptData
* @return $userInfo
*/
public static function encryptor($sessionKey, $iv, $encryptData){
return self::miniprogram()->encryptor->decryptData($sessionKey, $iv, $encryptData);
}
/**
* 上传临时素材接口
* @return \EasyWeChat\Material\Temporary
*/
public static function materialTemporaryService()
{
return self::miniprogram()->material_temporary;
}
/**
* 客服消息接口
* @param null $to
* @param null $message
*/
public static function staffService()
{
return self::miniprogram()->staff;
}
/**
* 微信小程序二维码生成接口
* @return \EasyWeChat\QRCode\QRCode
*/
public static function qrcodeService()
{
return self::miniprogram()->qrcode;
}
/**微信小程序二维码生成接口不限量永久
* @param $scene
* @param null $page
* @param null $width
* @param null $autoColor
* @param array $lineColor
* @return \Psr\Http\Message\StreamInterface
*/
public static function appCodeUnlimitService($scene, $page = null, $width = 430, $autoColor = false, $lineColor = ['r' => 0, 'g' => 0, 'b' => 0])
{
return self::qrcodeService()->appCodeUnlimit($scene,$page,$width,$autoColor,$lineColor);
}
/**
* 模板消息接口
* @return \EasyWeChat\Notice\Notice
*/
public static function noticeService()
{
return self::miniprogram()->notice;
}
/**发送小程序模版消息
* @param $openid
* @param $templateId
* @param array $data
* @param null $url
* @param null $defaultColor
* @return mixed
*/
public static function sendTemplate($openid,$templateId,array $data,$form_id,$link = null,$defaultColor = null)
{
$notice = self::noticeService()->to($openid)->template($templateId)->formId($form_id)->andData($data);
$message = [];
if($link !== null) $message = ['page'=>$link];
if($defaultColor !== null) $notice->defaultColor($defaultColor);
return $notice->send($message);
}
/**
* 支付
* @return \EasyWeChat\Payment\Payment
*/
public static function paymentService()
{
return self::application()->payment;
}
/**
* 生成支付订单对象
* @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
*/
protected static function paymentOrder($openid,$out_trade_no,$total_fee,$attach,$body,$detail='',$trade_type='JSAPI',$options = [])
{
$total_fee = bcmul($total_fee,100,0);
$order = array_merge(compact('openid','out_trade_no','total_fee','attach','body','detail','trade_type'),$options);
if($order['detail'] == '') unset($order['detail']);
return new Order($order);
}
/**
* 获得下单ID
* @param $openid
* @param $out_trade_no
* @param $total_fee
* @param $attach
* @param $body
* @param string $detail
* @param string $trade_type
* @param array $options
* @return mixed
*/
public static function paymentPrepare($openid, $out_trade_no, $total_fee, $attach, $body, $detail='', $trade_type='JSAPI', $options = [])
{
$order = self::paymentOrder($openid,$out_trade_no,$total_fee,$attach,$body,$detail,$trade_type,$options);
$result = self::paymentService()->prepare($order);
if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
try{
HookService::listen('wechat_payment_prepare_program',$order,$result->prepay_id,false,PaymentBehavior::class);
}catch (\Exception $e){}
return $result->prepay_id;
}else{
if($result->return_code == 'FAIL'){
exception('微信支付错误返回:'.$result->return_msg);
}else if(isset($result->err_code)){
exception('微信支付错误返回:'.$result->err_code_des);
}else{
exception('没有获取微信支付的预支付ID请重新发起支付!');
}
exit;
}
}
/**
* 获得jsSdk支付参数
* @param $openid
* @param $out_trade_no
* @param $total_fee
* @param $attach
* @param $body
* @param string $detail
* @param string $trade_type
* @param array $options
* @return array|string
*/
public static function jsPay($openid, $out_trade_no, $total_fee, $attach, $body, $detail='', $trade_type='JSAPI', $options = [])
{
return self::paymentService()->configForJSSDKPayment(self::paymentPrepare($openid,$out_trade_no,$total_fee,$attach,$body,$detail,$trade_type,$options));
}
/**
* 使用商户订单号退款
* @param $orderNo
* @param $refundNo
* @param $totalFee
* @param null $refundFee
* @param null $opUserId
* @param string $refundReason
* @param string $type
* @param string $refundAccount
*/
public static function refund($orderNo, $refundNo, $totalFee, $refundFee = null, $opUserId = null, $refundReason = '' , $type = 'out_trade_no', $refundAccount = 'REFUND_SOURCE_UNSETTLED_FUNDS')
{
$totalFee = floatval($totalFee);
$refundFee = floatval($refundFee);
return self::paymentService()->refund($orderNo,$refundNo,$totalFee,$refundFee,$opUserId,$type,$refundAccount,$refundReason);
}
/** 根据订单号退款
* @param $orderNo
* @param array $opt
* @return bool
*/
public static function payOrderRefund($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::refund($orderNo,$refundNo,$totalFee,$refundFee,$opUserId,$refundReason,$type,$refundAccount));
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()
{
self::paymentService()->handleNotify(function($notify, $successful){
if($successful && isset($notify->out_trade_no)){
return HookService::listen('wechat_pay_success',$notify,null,true,PaymentBehavior::class);
}
});
}
/**
* 作为客服消息发送
* @param $to
* @param $message
* @return bool
*/
public static function staffTo($to, $message)
{
$staff = self::staffService();
$staff = is_callable($message) ? $staff->message($message()) : $staff->message($message);
$res = $staff->to($to)->send();
HookService::afterListen('wechat_staff_to',compact('to','message'),$res);
return $res;
}
}