package com.gree.mall.manager.logic.common;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.profitsharing.*;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.ProfitSharingService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.gree.mall.manager.bean.PayDetail;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.common.WechatOpenBean;
import com.gree.mall.manager.bean.common.WxJsApiSignBean;
import com.gree.mall.manager.config.wx.WxConfiguration;
import com.gree.mall.manager.constant.Constant;
import com.gree.mall.manager.enums.OrderInfoSourceEnum;
import com.gree.mall.manager.enums.OrderShareStatusEnum;
import com.gree.mall.manager.enums.PayStatusEnum;
import com.gree.mall.manager.enums.SettlementStatusNewEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.*;
import com.gree.mall.manager.utils.oss.OSSUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by lijh on 19/06/28.
 */

@RequiredArgsConstructor
@Component
@Slf4j
public class WechatLogic {

    //环境
    @Value("${spring.profiles.active}")
    public String env;

    private final OSSUtil ossUtil;
    private final AdminCompanyWechatService adminCompanyWechatService;
    private final OrderInfoService orderInfoService;

    @Qualifier("zfireWxPay")
    @Autowired
    WxPayService wxPayService;

    @Autowired
    AdminWebsitService adminWebsitService;

    @Autowired
    AdminCompanyWechatPayConfigService adminCompanyWechatPayConfigService;

    @Autowired
    CommonLogic commonLogic;

    /**
     * 微信支付服务
     * @param companyWechatId
     * @param source 公众号 / 小程序
     * @return
     */
    public WxPayService getPayService(String companyWechatId,String source){
        if(StringUtils.equals(source,OrderInfoSourceEnum.A.getRemark())) {
            //小程序
            return WxConfiguration.wxSubPayServices.get(companyWechatId);
        }else{
            //公众号
            return WxConfiguration.wxPayServices.get(companyWechatId);
        }
    }

    /**
     * 微信支付服务
     * @param companyWechatId
     * @param source 公众号 / 小程序
     * @return
     */
    public WxPayService getPayWebstiService(String id,String source){

        return WxConfiguration.wxPayWebsitServices.get(id);

    }

    /**
     * 微信支付服务(小程序)
     * @param companyWechatId
     * @return
     */
//    public WxPayService getPayAppletService(String companyWechatId){
//        return WxConfiguration.wxSubPayServices.get(companyWechatId);
//    }

    /**
     * 微信小程序服务
     * @param companyWechatId
     * @return
     */
    public WxMaService getMaService(String companyWechatId){
        return WxConfiguration.wxMaService.get(companyWechatId);
    }

    /**
     * 微信公众号服务
     * @param companyWechatId
     * @return
     */
    public WxMpService getMpService(String companyWechatId){
        return WxConfiguration.wxMpServices.get(companyWechatId);
    }

    /**
     * 获取微信token
     *
     * @return
     * @throws RemoteServiceException
     */
    public String getAccessToken(String companyWechatId) throws RemoteServiceException, WxErrorException {
        return this.getMaService(companyWechatId).getAccessToken();
    }

    /**
     * 小程序授权openid
     * @param code
     * @param companyWechatId
     * @return
     * @throws RemoteServiceException
     */
    public WechatOpenBean authToken(String code, String companyWechatId) throws RemoteServiceException {
        try {
            WxMaJscode2SessionResult wxMaJscode2SessionResult = this.getMaService(companyWechatId).jsCode2SessionInfo(code);
            log.info("【微信授权response】:{}",JSONObject.toJSONString(wxMaJscode2SessionResult));
            WechatOpenBean bean = new WechatOpenBean();
            bean.setOpenid(wxMaJscode2SessionResult.getOpenid());
            bean.setUnionid(wxMaJscode2SessionResult.getUnionid());
            bean.setSessionKey(wxMaJscode2SessionResult.getSessionKey());
            return bean;
        } catch (WxErrorException e) {
            log.error("【微信授权失败】",e);
            throw new RemoteServiceException("授权失败，请联系相关人员");
        }
    }

    /**
     * 授权手机号
     * @param phoneCode
     * @param companyWechatId
     * @return
     */
    public String authMobile(String phoneCode,String companyWechatId){
        String phoneNumber = null;
        try {
            phoneNumber = this.getMaService(companyWechatId).getUserService().getPhoneNoInfo(phoneCode).getPhoneNumber();
        } catch (WxErrorException e) {
            log.error("【微信授权手机号失败】",e);
            throw new RemoteServiceException("授权手机号失败,请联系相关人员");
        }
        return phoneNumber ;
    }


    /**
     * 授权公众号openid
     * @param code
     * @param adminCompanyWechat
     * @return
     * @throws WxErrorException
     */
    public String pubAuthOpenId(String code,AdminCompanyWechat adminCompanyWechat) throws WxErrorException {

        WxOAuth2AccessToken accessToken = getMpService(adminCompanyWechat.getCompanyWechatId()).getOAuth2Service().getAccessToken(code);
        String openId = accessToken.getOpenId();
        return openId;
    }


    /**
     * 发货到微信
     * @param orderInfo
     */
    public void deliver(OrderInfo orderInfo, String openId) throws WxErrorException {
        if(StringUtils.equals(orderInfo.getSource(),OrderInfoSourceEnum.A.getRemark())) {
            this.deliver(orderInfo.getCompanyWechatId(), orderInfo.getTransactionId(), orderInfo.getOrderTitle(), openId);
        }
    }


    /**
     * 发货到微信
     * @param companyWechatId
     * @param transactionId
     * @param orderTitle
     * @param openId
     * @throws WxErrorException
     */
    public void deliver(String companyWechatId,String transactionId,String orderTitle,String openId) throws WxErrorException {
        //        if(!StringUtils.equals(env,"prd")){
//            return;
//        }
        if(StringUtils.isBlank(transactionId)){
            log.error("发货到微信失败，微信流水号为空");
            return;
        }
        if(StringUtils.isBlank(orderTitle)){
            orderTitle = "辅材配件费用";
        }
        String token = this.getAccessToken(companyWechatId);
        String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token="+token;
        Map<String,Object> map = new HashMap<>();
        //map.put("access_token",token);
        //1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
        map.put("logistics_type",2);
        map.put("delivery_mode",1);
        map.put("upload_time",String.valueOf(LocalDateTime.now())+"+08:00");

        Map<String,Object> order_key = new HashMap<>();
        order_key.put("order_number_type",2);
        order_key.put("transaction_id",transactionId);
        map.put("order_key",order_key);

        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> shoppingMap = new HashMap<>();
        shoppingMap.put("item_desc",orderTitle);
        //shoppingMap.put("tracking_no",logisticsNo);
        list.add(shoppingMap);
        map.put("shipping_list",list);

        Map<String,String> payerMap = new HashMap<>();
        payerMap.put("openid",openId);
        map.put("payer",payerMap);

        log.info("【对接微信发货】request:{}",JSONObject.toJSONString(map));
        String s = HttpUtils.requestPostBody(url, JSONObject.toJSONString(map), null);
        log.info("【对接微信发货】response:{}",s);
        JSONObject jsonObject = JSONObject.parseObject(s);
        //找不到支付单 或 已发货
        if(jsonObject.getInteger("errcode") == 10060001 || jsonObject.getInteger("errcode") == 10060023){
            return ;
        }
        //其他错误
        if(jsonObject.getInteger("errcode") != 0){
            log.error("同步微信发货失败："+JSONObject.toJSONString(jsonObject));
            throw new RemoteServiceException("同步微信发货失败，请联系相关人员");
        }
    }



    /**
     * 付款码支付
     * @param id 单号
     * @param payment 支付金额
     * @param profitSharingFlag 是否分账 Y=分
     * @param ip 请求ip
     * @param companyWechatId 商户号id
     * @param authCode 付款码扫码得到的code
     * @return
     */
    public String paymentFkm(String id,BigDecimal payment,String profitSharingFlag,String ip,String companyWechatId,String authCode,String source){

        WxPayService payService = this.getPayService(companyWechatId,source);

        WxPayMicropayRequest request = new WxPayMicropayRequest();
        //request.setDeviceInfo(worker.getWorkerId());
        request.setBody("售修宝费用");
        request.setOutTradeNo(id);
        request.setTotalFee(payment.multiply(new BigDecimal("100")).intValue());
        request.setSpbillCreateIp(ip);
        request.setAuthCode(authCode);
        request.setProfitSharing(profitSharingFlag); // 分账标记 Y=分账 N=不分账

        WxPayMicropayResult payResult = null;
        try {
            payResult = payService.micropay(request);
            log.info("商户扫码支付生成订单响应: {}", payResult);
        } catch (WxPayException e) {
            log.error("商户扫码支付失败: {}", payResult);
            throw new RemoteServiceException("扫码支付失败,请检查二维码是否正确");
        }
        if (payResult == null || WxPayConstants.ResultCode.FAIL.equals(payResult.getReturnCode())) {
            throw new RemoteServiceException("扫码支付失败,请检查二维码是否正确");
        }
        //记录流水
        AdminCompanyWechat adminCompanyWechat = adminCompanyWechatService.getById(companyWechatId);
        this.addPayRecord(adminCompanyWechat,payment,"",payResult.getSubOpenid(),ip,payResult.getTradeType(),id,payResult.getTransactionId());
        return payResult.getTransactionId();
    }

    /**
     * h5支付
     * @param id
     * @param payment
     * @param openId
     * @param profitSharingFlag
     * @param ip
     * @param companyWechatId
     * @return
     * @throws Exception
     */
    public PayDetail paymentH5(String id,BigDecimal payment,String openId,String profitSharingFlag,String ip,String companyWechatId) throws Exception {
        return this.payment(id,payment,openId,profitSharingFlag,ip,companyWechatId,"MWEB",false);
    }


    /**
     * 小程序支付
     * @param id
     * @param payment
     * @param openId
     * @param profitSharingFlag
     * @param ip
     * @param companyWechatId
     * @return
     * @throws Exception
     */
    public PayDetail paymentJSAPI(String id,BigDecimal payment,String openId,String profitSharingFlag,String ip,String companyWechatId,Boolean miniPay) throws Exception {
        return this.payment(id,payment,openId,profitSharingFlag,ip,companyWechatId,"JSAPI",miniPay);
    }

    /**
     * 扫码支付，返回codeUrl需要装二维码里
     * @param id  单号
     * @param payment 需要支付的金额
     * @param openId
     * @param profitSharingFlag Y=分账 N=不分账
     * @param ip
     * @param companyWechatId
     * @return
     * @throws Exception
     */
    public PayDetail paymentNATIVE(String id,BigDecimal payment,String openId,String profitSharingFlag,String ip,String companyWechatId) throws Exception {
        return this.payment(id,payment,openId,profitSharingFlag,ip,companyWechatId,"NATIVE",false);
    }

    /**
     * 微信支付 JSAPI
     * @param id
     * @param payment
     * @param openId
     * @return
     * @throws Exception
     */
    private PayDetail payment(String id, BigDecimal payment, String openId, String profitSharingFlag, String ip, String companyWechatId,String tradeType,Boolean miniPay) throws Exception {

        if(payment.doubleValue() <= 0){
            //throw new RemoteServiceException("支付金额小于等于0,实际支付金额："+payment);
            PayDetail payDetail = new PayDetail();
            payDetail.setIsPay(false);
            payDetail.setId(id);
            return payDetail;
        }
        //撤销订单
        //this.reverse(id,companyWechatId);
        String source = miniPay != null && miniPay ? OrderInfoSourceEnum.A.getRemark() : OrderInfoSourceEnum.B.getRemark();
        WxPayService payService =this.getPayService(companyWechatId,source);

        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setBody("商城支付费用");
        wxPayUnifiedOrderRequest.setTotalFee((int)ArithUtils.mul(payment.doubleValue(), 100));
        wxPayUnifiedOrderRequest.setSubOpenid(openId);
        wxPayUnifiedOrderRequest.setNonceStr(StringUtil.getUUID());
        wxPayUnifiedOrderRequest.setOutTradeNo(id +"-"+ StringUtil.getRandomSMS());
        wxPayUnifiedOrderRequest.setAttach(id);//支付通过该方式回调处理
        //wxPayUnifiedOrderRequest.setTradeType("JSAPI");
        wxPayUnifiedOrderRequest.setTradeType(tradeType);
        wxPayUnifiedOrderRequest.setProductId(id);
        wxPayUnifiedOrderRequest.setNotifyUrl(payService.getConfig().getNotifyUrl());
        wxPayUnifiedOrderRequest.setSpbillCreateIp(ip);
        wxPayUnifiedOrderRequest.setProfitSharing(profitSharingFlag);
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = payService.unifiedOrder(wxPayUnifiedOrderRequest);
        log.info("服务商调起支付result:{}",JSONObject.toJSONString(wxPayUnifiedOrderResult));
        String returnCode = wxPayUnifiedOrderResult.getReturnCode();
        if (!StringUtils.equals(returnCode, "SUCCESS")) {
            throw new RemoteServiceException( "微信调起支付失败：" + wxPayUnifiedOrderResult.getReturnMsg());
        }

        //二次签名
        String time = System.currentTimeMillis() / 1000 + "";
        String prepayId = "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId();
        String nonceStr = wxPayUnifiedOrderResult.getNonceStr();
        String twoSign = this.getTwoSign(prepayId, nonceStr, time,payService.getConfig().getSubAppId(),payService.getConfig().getMchKey());
        PayDetail payDetail = new PayDetail();
        payDetail.setPayPackage(prepayId);
        payDetail.setPaySign(twoSign);
        payDetail.setNonceStr(wxPayUnifiedOrderResult.getNonceStr());
        payDetail.setTimeStamp(time);
        payDetail.setCodeUrl(wxPayUnifiedOrderResult.getCodeURL());
        //h5的url
        if(StringUtils.isNotBlank(wxPayUnifiedOrderResult.getMwebUrl())) {
            payDetail.setCodeUrl(wxPayUnifiedOrderResult.getMwebUrl());
        }
        payDetail.setId(id);
        log.info("payDetail:{}",JSONObject.toJSONString(payDetail));
        return payDetail;
    }


    /**
     * 众炬平台续费使用
     * @throws WxPayException
     */
//    public void zfirePayment() throws WxPayException {
//        String id = IdWorker.getIdStr();
//        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
//        wxPayUnifiedOrderRequest.setBody("售修宝支付费用");
//        wxPayUnifiedOrderRequest.setTotalFee((int)ArithUtils.mul(0.01, 100));
//        wxPayUnifiedOrderRequest.setNonceStr(StringUtil.getUUID());
//        wxPayUnifiedOrderRequest.setOutTradeNo(IdWorker.getIdStr() +"-"+ StringUtil.getRandomSMS());
//        wxPayUnifiedOrderRequest.setAttach(id);//支付通过该方式回调处理
//        //wxPayUnifiedOrderRequest.setTradeType("JSAPI");
//        wxPayUnifiedOrderRequest.setTradeType("NATIVE");
//        wxPayUnifiedOrderRequest.setProductId(id);
//        wxPayUnifiedOrderRequest.setNotifyUrl(wxPayService.getConfig().getNotifyUrl());
//        wxPayUnifiedOrderRequest.setSpbillCreateIp("183.6.114.237");
//
//        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
//        log.info("服务商调起支付result:{}",JSONObject.toJSONString(wxPayUnifiedOrderResult));
//    }


    /**
     * 服务商退款
     */
    public void refund(String transacationId, String refundNo, Double totalFee, Double refundFee,String companyWechatId,String source) throws  RemoteServiceException {
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setTransactionId(transacationId);
        //wxPayRefundRequest.setOutTradeNo(orderId);
        wxPayRefundRequest.setOutRefundNo(refundNo);
        wxPayRefundRequest.setRefundFee((int) ArithUtils.mul(refundFee, 100));
        wxPayRefundRequest.setTotalFee((int) ArithUtils.mul(totalFee, 100));
        wxPayRefundRequest.setNonceStr(StringUtil.getUUID());
//        wxPayRefundRequest.setNotifyUrl(refundNotifyUrl);
        if(refundFee == 0){
            throw new RemoteServiceException("当前订单不可退款");
        }
        log.info("【申请微信退款】request=" + JSONObject.toJSONString(wxPayRefundRequest));
        try {

            WxPayRefundResult refund =  this.getPayService(companyWechatId,source).refund(wxPayRefundRequest);

            log.info("【申请微信退款】result=" + JSONObject.toJSONString(refund));

            if (!StringUtils.equals(refund.getReturnCode(), "SUCCESS")) {
                throw new RemoteServiceException(refund.getReturnCode() + refund.getReturnMsg());
            }
        }catch (WxPayException ex){
            log.error("【微信退款失败】:",ex);
            throw new RemoteServiceException("退款失败："+ex.getMessage());
        }

    }

    /**
     * 增值服务模块服务商退款
     */
//    public void increRefund(String transacationId, String outTradeNo, String refundNo, Double totalFee, Double refundFee,String companyWechatId) throws  RemoteServiceException {
//        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
//        if (StringUtils.isBlank(outTradeNo)) {
//            wxPayRefundRequest.setTransactionId(transacationId);
//        } else {
//            wxPayRefundRequest.setOutTradeNo(outTradeNo);
//        }
//        wxPayRefundRequest.setOutRefundNo(refundNo);
//        wxPayRefundRequest.setRefundFee((int) ArithUtils.mul(refundFee, 100));
//        wxPayRefundRequest.setTotalFee((int) ArithUtils.mul(totalFee, 100));
//        wxPayRefundRequest.setNonceStr(StringUtil.getUUID());
////        wxPayRefundRequest.setNotifyUrl(refundNotifyUrl);
//
//        log.info("【申请微信退款】request=" + JSONObject.toJSONString(wxPayRefundRequest));
//        try {
//            WxPayRefundResult refund = this.getPayService(companyWechatId).refund(wxPayRefundRequest);
//            log.info("【申请微信退款】result=" + JSONObject.toJSONString(refund));
//
//            if (!StringUtils.equals(refund.getReturnCode(), "SUCCESS")) {
//                throw new RemoteServiceException(refund.getReturnCode() + refund.getReturnMsg());
//            }
//        }catch (WxPayException ex){
//            log.error("【微信退款失败】:",ex);
//            throw new RemoteServiceException("退款失败："+ex.getMessage());
//        }
//
//    }

    /**
     * 撤销订单
     * @param orderId
     * @param companyWechatId
     * @throws WxPayException
     */
//    public void reverse(String orderId,String companyWechatId) throws WxPayException {
//        this.getPayService(companyWechatId).closeOrder(orderId);
//    }


    /**
     * 记录支付流水
     * @param adminCompanyWechat
     * @param payment 支付金额
     * @param mobile 付款人手机号
     * @param ip 付款人ip地址
     * @param tradeType JSAPI=小程序支付  NATIVE=扫码支付  MICROPAY=付款码
     * @param orderId 订单号
     * @param transacationId 微信支付流水号
     */
    public void addPayRecord(AdminCompanyWechat adminCompanyWechat,BigDecimal payment,String mobile,String openId,String ip,String tradeType,String orderId,String transacationId){
        PayRecord payRecord = new PayRecord();
        payRecord.setCompanyWechatId(adminCompanyWechat.getCompanyWechatId());
        payRecord.setCompanyWechatName(adminCompanyWechat.getCompanyName());
        payRecord.setAppId(adminCompanyWechat.getAppId());
        payRecord.setSubAppId(adminCompanyWechat.getSubAppId());
        payRecord.setSubMchId(adminCompanyWechat.getSubMchId());
        payRecord.setOpenId(openId);
        payRecord.setIp(ip);
        payRecord.setPayment(payment);
        payRecord.setMobile(mobile);
        payRecord.setTradeType(tradeType);
        payRecord.setOutTradeNo(orderId);
        payRecord.setTransactionId(transacationId);
        payRecord.setCreateTime(new Date());
        payRecord.insert();
    }

    /**
     * 记录支付流水
     * @param adminCompanyWechat
     * @param payment 支付金额
     * @param mobile 付款人手机号
     * @param ip 付款人ip地址
     * @param tradeType JSAPI=小程序支付  NATIVE=扫码支付  MICROPAY=付款码
     * @param orderId 订单号
     * @param transacationId 微信支付流水号
     */
    public void addPayWebsitRecord(AdminCompanyWechatPayConfig adminCompanyWechat,BigDecimal payment,String mobile,String openId,String ip,String tradeType,String orderId,String transacationId){
        PayRecord payRecord = new PayRecord();
        payRecord.setCompanyWechatId(adminCompanyWechat.getCompanyWechatId());
        payRecord.setCompanyWechatName(adminCompanyWechat.getCompanyName());
        payRecord.setAppId(adminCompanyWechat.getAppId());
        payRecord.setSubAppId(adminCompanyWechat.getSubAppId());
        payRecord.setSubMchId(adminCompanyWechat.getSubMchId());
        payRecord.setOpenId(openId);
        payRecord.setIp(ip);
        payRecord.setPayment(payment);
        payRecord.setMobile(mobile);
        payRecord.setTradeType(tradeType);
        payRecord.setOutTradeNo(orderId);
        payRecord.setTransactionId(transacationId);
        payRecord.setCreateTime(new Date());
        payRecord.insert();
    }


    /**
     * 电子支付分账
     * @param settlementOrder
     * @throws WxPayException
     */
    public void shareSettlementAmount(SettlementOrder settlementOrder) throws WxPayException {

        AdminUserCom adminUser = commonLogic.getAdminUser();
        if(settlementOrder == null){
            return;
        }
        if(!StringUtils.equals(settlementOrder.getPayStatus(), PayStatusEnum.PAID.getKey())){
            throw new RemoteServiceException("未支付订单不可结算");
        }
        if(!StringUtils.equals(settlementOrder.getStatus(),"WAIT")){
            log.error("非待结算状态不可结算,id:{}",settlementOrder.getOrderId());
            return;
        }
        Map<String,BigDecimal> map = new HashMap<>();
        map.put(settlementOrder.getOpenId(),settlementOrder.getWorkerAmount());
        Map<String,String> mapPhone = new HashMap<>();
        mapPhone.put(settlementOrder.getOpenId(),settlementOrder.getWorkerMobile());
        //开始分账
        try {
            profitSettlementSharing(settlementOrder.getOrderId(), settlementOrder.getTranscationId(), map, mapPhone,
                    settlementOrder.getCompanyWechatId(), "B",settlementOrder.getConfigId());

            settlementOrder.setStatus(SettlementStatusNewEnum.OK.toString());
            settlementOrder.setSettlementTime(new Date());
            settlementOrder.setSettlementName(adminUser.getNickName());
            settlementOrder.updateById();

        } catch (WxPayException e) {
            log.error("异常结算", e);

            settlementOrder.setStatus(SettlementStatusNewEnum.YC.toString());
            settlementOrder.setYcRemark(e.getMessage());
            settlementOrder.updateById();
        }
    }

    /**
     * 电子支付分账-定时
     * @param settlementOrder
     * @throws WxPayException
     */
    public void shareSettlementAmountCorn(SettlementOrder settlementOrder) throws WxPayException {

        if(settlementOrder == null){
            return;
        }
        if(!StringUtils.equals(settlementOrder.getPayStatus(), PayStatusEnum.PAID.getKey())){
            throw new RemoteServiceException("未支付订单不可结算");
        }
        if(!StringUtils.equals(settlementOrder.getStatus(),"WAIT")){
            log.error("非待结算状态不可结算,id:{}",settlementOrder.getOrderId());
            return;
        }
        Map<String,BigDecimal> map = new HashMap<>();
        map.put(settlementOrder.getOpenId(),settlementOrder.getWorkerAmount());
        Map<String,String> mapPhone = new HashMap<>();
        mapPhone.put(settlementOrder.getOpenId(),settlementOrder.getWorkerMobile());
        //开始分账
        try {
            profitSettlementSharing(settlementOrder.getOrderId(), settlementOrder.getTranscationId(), map, mapPhone,
                    settlementOrder.getCompanyWechatId(), "B",settlementOrder.getConfigId());

            settlementOrder.setStatus(SettlementStatusNewEnum.OK.toString());
            settlementOrder.setSettlementTime(new Date());
            settlementOrder.updateById();

        } catch (WxPayException e) {
            log.error("异常结算", e);

            settlementOrder.setStatus(SettlementStatusNewEnum.YC.toString());
            settlementOrder.setYcRemark(e.getMessage());
            settlementOrder.updateById();
        }
    }



    /**
     * 分账
     * @param orderSharingId 分账id
     * @param transactionId 微信支付流水号
     * @param amountMap  key=分钱人的openid   value=分多少钱
     * @param phoneMap key=分钱人的openid  value=手机号
     * @param companyWechatId 商户id
     * @param source
     * @throws WxPayException
     */
    private void profitSettlementSharing(String orderSharingId, String transactionId, Map<String, BigDecimal> amountMap,
                               Map<String, String> phoneMap, String companyWechatId, String source,String config) throws WxPayException {

        List<Map<String, Object>> list = new ArrayList<>();

        for(String openId : amountMap.keySet()){
            //添加分账人
            addShareReveiver(openId,config,source);

            BigDecimal shareAmount = amountMap.get(openId);
            String workerUserPhone = phoneMap.get(openId);
            if(shareAmount.doubleValue() == 0){
                continue;
            }
            Map<String, Object> receiver = new HashMap<>();
            receiver.put("type", "PERSONAL_SUB_OPENID");
            receiver.put("account", openId);
            receiver.put("amount", ProfitSharingReceiverRequest.yuanToFen(shareAmount.toString()));
            receiver.put("description", "销售返佣给" + workerUserPhone + "，金额：" + shareAmount + "元");
            list.add(receiver);
        }

        ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
        profitSharingRequest.setOutOrderNo(orderSharingId);
        profitSharingRequest.setTransactionId(transactionId);
        profitSharingRequest.setReceivers(JSONObject.toJSONString(list));

        ProfitSharingService profitSharingService = this.getPayWebstiService(config, source).getProfitSharingService();
        //请求单次分账
        log.info("【开始分账】request:{}", JSONObject.toJSONString(profitSharingRequest));
        profitSharingService.profitSharing(profitSharingRequest);
        //log.info("【开始分账】result:{}", JSONObject.toJSONString(profitSharingResult));

    }





    /**
     * 商城订单分账
     * @param orderId
     * @param transactionId
     * @param orderShares
     * @throws WxPayException
     */
    public void shareAmount(String orderId, String transactionId, List<OrderShare> orderShares,String companyWechatId) throws WxPayException {
        // 查询订单金额分销表需要分佣记录
        List<String> openIds = orderShares.stream()
                .map(OrderShare::getOpenId)
                .distinct()
                .collect(Collectors.toList());

        Map<String,BigDecimal> map = new HashMap<>();
        Map<String,String> mapPhone = new HashMap<>();
        for(String openId : openIds){
            // 计算每个openid需要分佣总金额
            BigDecimal totalShareAmount = orderShares.stream()
                    .filter(v -> v.getOpenId().equals(openId))
                    .map(OrderShare::getAmount)
                    .reduce(BigDecimal::add)
                    .orElse(BigDecimal.valueOf(0));

            String phone = orderShares.stream()
                    .filter(v -> v.getOpenId().equals(openId))
                    .map(OrderShare::getWorkUserPhone)
                    .collect(Collectors.toList())
                    .get(0);

            map.put(openId,totalShareAmount);
            mapPhone.put(openId,phone);
        }
        // 查询商城订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        //开始分账
        profitSharing(orderId, transactionId, map, mapPhone, companyWechatId, orderInfo.getSource());
    }

    /**
     * 增置服务订单分账
     * @param pgIncreOrder
     */
    public void shareAmount(PgIncreOrder pgIncreOrder){
        if(pgIncreOrder == null){
            return;
        }
        if(!StringUtils.equals(pgIncreOrder.getPayStatus(), PayStatusEnum.PAID.getKey())){
            throw new RemoteServiceException("未支付订单不可结算");
        }
        if(!StringUtils.equals(pgIncreOrder.getSettleStatus(),OrderShareStatusEnum.ING.toString())){
            log.error("非待结算状态不可结算,id:{}",pgIncreOrder.getId());
            return;
        }
        Map<String,BigDecimal> map = new HashMap<>();
        map.put(pgIncreOrder.getWorkerOpenId(),pgIncreOrder.getWorkerAmount());
        Map<String,String> mapPhone = new HashMap<>();
        mapPhone.put(pgIncreOrder.getWorkerOpenId(),pgIncreOrder.getWorkerMobile());
        //开始分账
        try {
            profitSharing(pgIncreOrder.getId(), pgIncreOrder.getTranscationId(), map, mapPhone, pgIncreOrder.getCompanyWechatId(), pgIncreOrder.getSource());

            pgIncreOrder.setSettleStatus(OrderShareStatusEnum.OVER.toString());
            pgIncreOrder.setSettleRemark("分账成功");
            pgIncreOrder.updateById();

        } catch (WxPayException e) {
            log.error("异常结算", e);
            pgIncreOrder.setSettleRemark("异常结算："+e.getErrCodeDes());
            pgIncreOrder.setSettleStatus(OrderShareStatusEnum.EXCEPTION.toString());
            pgIncreOrder.updateById();
        }
    }


    /**
     * 分账
     * @param orderSharingId 分账id
     * @param transactionId 微信支付流水号
     * @param amountMap  key=分钱人的openid   value=分多少钱
     * @param phoneMap key=分钱人的openid  value=手机号
     * @param companyWechatId 商户id
     * @param source
     * @throws WxPayException
     */
    private void profitSharing(String orderSharingId, String transactionId, Map<String, BigDecimal> amountMap,
                               Map<String, String> phoneMap, String companyWechatId, String source) throws WxPayException {

        List<Map<String, Object>> list = new ArrayList<>();

        for(String openId : amountMap.keySet()){
            //添加分账人
            addShareReveiver(openId,companyWechatId,source);

            BigDecimal shareAmount = amountMap.get(openId);
            String workerUserPhone = phoneMap.get(openId);
            if(shareAmount.doubleValue() == 0){
                continue;
            }
            Map<String, Object> receiver = new HashMap<>();
            receiver.put("type", "PERSONAL_SUB_OPENID");
            receiver.put("account", openId);
            receiver.put("amount", ProfitSharingReceiverRequest.yuanToFen(shareAmount.toString()));
            receiver.put("description", "销售返佣给" + workerUserPhone + "，金额：" + shareAmount + "元");
            list.add(receiver);
        }

        ProfitSharingRequest profitSharingRequest = new ProfitSharingRequest();
        profitSharingRequest.setOutOrderNo(orderSharingId);
        profitSharingRequest.setTransactionId(transactionId);
        profitSharingRequest.setReceivers(JSONObject.toJSONString(list));

        ProfitSharingService profitSharingService = this.getPayService(companyWechatId, source).getProfitSharingService();
        //请求单次分账
        log.info("【开始分账】request:{}", JSONObject.toJSONString(profitSharingRequest));
        profitSharingService.profitSharing(profitSharingRequest);
        //log.info("【开始分账】result:{}", JSONObject.toJSONString(profitSharingResult));

    }

    private boolean addShareReveiver(String openId,String companyWechatId,String source) {
        Map<String, Object> receiver = new HashMap<>();
        /**
         *  MERCHANT_ID:商户号
         *  PERSONAL_OPENID:个人openId(由父商户号APPID转换得到)
         *  PERSONAL_SUB_OPENID:个人sub_openid（由子商户APPID转换得到）
         */
        receiver.put("type", "PERSONAL_SUB_OPENID");
        /**
         * 分账接收方类型为MERCHANT_ID时，分账接收方账号为商户号
         * 分账接收方类型为PERSONAL_OPENID时，分账接收方账号为个人openid
         * 分账接收方类型为PERSONAL_SUB_OPENID时，分账接收方账号为个人sub_openid
         */
        receiver.put("account", openId);
        //receiver.put("name",name);
        receiver.put("relation_type", "STAFF");
        //添加分账人
        ProfitSharingService profitSharingService = this.getPayWebstiService(companyWechatId,source).getProfitSharingService();

        ProfitSharingReceiverRequest profitSharingReceiverRequest = new ProfitSharingReceiverRequest();
        profitSharingReceiverRequest.setReceiver(JSONObject.toJSONString(receiver));
        ProfitSharingReceiverResult result = null;
        try {
            result = profitSharingService.addReceiver(profitSharingReceiverRequest);
            if (result.getReturnCode().equals("SUCCESS")) {
                return true;
            }
        } catch (WxPayException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void profitSharingFinish(OrderInfo orderInfo) throws WxPayException {
        final String companyWechatId = orderInfo.getCompanyWechatId();
        final String source = orderInfo.getSource();
        ProfitSharingFinishRequest finishRequest = new ProfitSharingFinishRequest();
        finishRequest.setOutOrderNo(orderInfo.getOrderId());
        finishRequest.setTransactionId(orderInfo.getTransactionId());
        finishRequest.setDescription("无分佣，完结分账");
        ProfitSharingService profitSharingService = this.getPayService(companyWechatId, source).getProfitSharingService();
        //请求单次分账
        log.info("【完结分账】request:{}", JSONObject.toJSONString(finishRequest));
        profitSharingService.profitSharingFinish(finishRequest);
    }


    /**
     * 获取微信二维码
     * @param type 二维码类型
     * @param objId 商品id/券id 之类的
     * @param userId 生成二维码的用户id
     * @param companyWechatId 商户id
     * @return
     */
    public String getQrcode(String type,String objId,String userId,String companyWechatId){
        String param = type + "&" + objId + "&" + userId;
        WxScene wxScene = new WxScene();
        wxScene.setParam(param);
        wxScene.setType(type);
        wxScene.setCreateTime(new Date());
        wxScene.insert();
        return this.genQrCode(wxScene.getSceneId(),companyWechatId);
    }

    public String getZdhf(String companyWechatId) throws WxErrorException {
        WxMpCurrentAutoReplyInfo currentAutoReplyInfo = this.getMpService(companyWechatId).getCurrentAutoReplyInfo();
        log.info("【自动回复内容】:{}",JSONObject.toJSONString(currentAutoReplyInfo));
        String content = currentAutoReplyInfo.getAddFriendAutoReplyInfo().getContent();
        return content;
    }



    /**
     * 生成二维码
     * @param sceneId
     * @param companyWechatId
     * @return
     */
    private String genQrCode(String sceneId,String companyWechatId){
        try {

            String token = this.getAccessToken(companyWechatId);

            Map<String, Object> params = new HashMap<>();
            params.put("scene", sceneId);  //参数
            params.put("page", "pages/index/index"); //位置
            params.put("width", 430);

            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token);
            httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
            String body = JSON.toJSONString(params);
            StringEntity entity;
            entity = new StringEntity(body);
            entity.setContentType("image/png");

            httpPost.setEntity(entity);
            HttpResponse response;
            response = httpClient.execute(httpPost);
            InputStream in = response.getEntity().getContent();
            //流转换为二进制数组，read()是转换方法
            byte[] data = new byte[1024];
            int len = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while ((len = in.read(data)) != -1) {
                bos.write(data, 0, len);
            }
            bos.close();

            //String baseStr = Base64.getEncoder().encodeToString(bos.toByteArray());
            long currentTime = System.currentTimeMillis();
            String filePath = ossUtil.getFilePath()+"/"+ currentTime + UUID.randomUUID().toString() + ".png";
            ossUtil.uploadFile(filePath, bos.toByteArray());

            return ossUtil.getAccessUrl() + filePath;
        }catch (Exception e){
            log.error("获取微信二维码失败:",e);
        }
        return null;
    }


    public String getUrlScheme(String query,String companyWechatId) throws IOException, WxErrorException {
        if(StringUtils.isBlank(companyWechatId)){
            companyWechatId = Constant.GD_COMPANY_WECHAT_ID;
        }
        String accessToken = this.getMaService(companyWechatId).getAccessToken();
        HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/wxa/generatescheme?access_token="+accessToken);
        httpPost.setHeader("Content-Type","application/json; charset=utf-8");
        httpPost.setConfig(RequestConfig.custom().setConnectTimeout(10*1000).build());

        TreeMap<String,String>  jump_wxa=new TreeMap<>();
        jump_wxa.put("query",query);

        TreeMap<String,Object> treeMap=new TreeMap<>();
        treeMap.put("jump_wxa",jump_wxa);
        httpPost.setEntity(new StringEntity(JSON.toJSONString(treeMap)));

        HttpResponse httpResponse = HttpClientBuilder.create().build().execute(httpPost);
        String s = EntityUtils.toString(httpResponse.getEntity());
        if(httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
            log.info("调用微信接口失败:"+httpPost.getURI());
            log.info("返回数据："+s);
            throw new RuntimeException("调用微信接口失败");
        }
        log.info("调用微信接口成功:"+httpPost.getURI());
        log.info("微信接口返回数据："+s);

        try{
            return JSON.parseObject(s).get("openlink").toString();
        }catch (NullPointerException e){
            return s;
        }
    }


     //二次签名
    public String getTwoSign(String payPackage, String nonceStr, String time,String subAppId,String mchKey) {
        Map<String, String> map = new HashMap<>();
        map.put("appId",subAppId);
        map.put("timeStamp", time);
        map.put("nonceStr", nonceStr);
        map.put("package", payPackage);
        map.put("signType", "MD5");
        String stringA = Utils.formatUrlMap(map, false, false);
        String sign = MD5Utils.md5(stringA + "&key=" +mchKey).toUpperCase();
        return sign;
    }


    /**
     * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序），并且生成url参数串<br>
     * 实现步骤: <br>
     *
     * @param paraMap    要排序的Map对象
     * @param urlEncode  是否需要URLENCODE
     * @param keyToLower 是否需要将Key转换为全小写
     *                   true:key转化成小写，false:不转化
     * @return
     */
    private static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower) {
        String buff = "";
        Map<String, String> tmpMap = paraMap;
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
                @Override
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造URL 键值对的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (StringUtils.isNotBlank(item.getKey())) {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (urlEncode) {
                        val = URLEncoder.encode(val, "utf-8");
                    }
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }

            }
            buff = buf.toString();
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
            return null;
        }
        return buff;
    }


    //xml解析
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        Map m = new HashMap();
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        for (Object aList : list) {
            Element e = (Element) aList;
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }
            m.put(k, v);
        }
        //关闭流
        in.close();
        return m;
    }

    private static String getChildrenText(List children) {
        StringBuilder sb = new StringBuilder();
        if (!children.isEmpty()) {
            for (Object aChildren : children) {
                Element e = (Element) aChildren;
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<").append(name).append(">");
                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</").append(name).append(">");
            }
        }

        return sb.toString();
    }

    /**
     * 服务收费
     * @param id
     * @param payment
     * @param openId
     * @return
     * @throws Exception
     */
    public PayDetail serviceNormPayment(String id, BigDecimal payment, String openId, String ip, String companyWechatId) throws Exception {

        if(payment.doubleValue() <= 0){
            //throw new RemoteServiceException("支付金额小于等于0,实际支付金额："+payment);
            PayDetail payDetail = new PayDetail();
            payDetail.setIsPay(false);
            payDetail.setId(id);
            return payDetail;
        }


        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setBody("服务收费");
        wxPayUnifiedOrderRequest.setTotalFee((int)ArithUtils.mul(payment.doubleValue(), 100));
        wxPayUnifiedOrderRequest.setNonceStr(StringUtil.getUUID());
        wxPayUnifiedOrderRequest.setOutTradeNo(id +"-"+ StringUtil.getRandomSMS());
        wxPayUnifiedOrderRequest.setAttach(id);//支付通过该方式回调处理
        wxPayUnifiedOrderRequest.setTradeType("NATIVE");
        wxPayUnifiedOrderRequest.setProductId(id);
        wxPayUnifiedOrderRequest.setNotifyUrl(wxPayService.getConfig().getNotifyUrl());
        wxPayUnifiedOrderRequest.setSpbillCreateIp(ip);
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
        log.info("普通商户调起支付result:{}",JSONObject.toJSONString(wxPayUnifiedOrderResult));
        String returnCode = wxPayUnifiedOrderResult.getReturnCode();
        if (!StringUtils.equals(returnCode, "SUCCESS")) {
            throw new RemoteServiceException( "微信调起支付失败：" + wxPayUnifiedOrderResult.getReturnMsg());
        }

        //二次签名
        String time = System.currentTimeMillis() / 1000 + "";
        String prepayId = "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId();
        String nonceStr = wxPayUnifiedOrderResult.getNonceStr();
        String twoSign = this.getTwoSign(prepayId, nonceStr, time,wxPayService.getConfig().getSubAppId(),wxPayService.getConfig().getMchKey());
        PayDetail payDetail = new PayDetail();
        payDetail.setPayPackage(prepayId);
        payDetail.setPaySign(twoSign);
        payDetail.setNonceStr(wxPayUnifiedOrderResult.getNonceStr());
        payDetail.setTimeStamp(time);
        payDetail.setCodeUrl(wxPayUnifiedOrderResult.getCodeURL());
        payDetail.setId(id);
        log.info("payDetail:{}",JSONObject.toJSONString(payDetail));
        return payDetail;
    }


    /**
     * 获取公众号 jsapiTicket
     * @return
     */
    public WxJsApiSignBean getJsapiSign(String companyWechatId,String url) throws WxErrorException {
        WxJsapiSignature jsapiSignature = getMpService(companyWechatId).createJsapiSignature(url);
        WxJsApiSignBean wxJsApiSignBean = BeanUtil.copyProperties(jsapiSignature, WxJsApiSignBean.class);
        return wxJsApiSignBean;
    }


    public WxMpQrCodeTicket getMpQrcode(String userId, String companyWechatId) throws WxErrorException {
        WxMpService wxMpService = getMpService(companyWechatId);
        if (Objects.isNull(wxMpService)) {
            throw new RemoteServiceException("配置错误");
        }
        WxMpQrcodeService qrcodeService = wxMpService.getQrcodeService();
        WxMpQrCodeTicket ticket = qrcodeService.qrCodeCreateTmpTicket(userId, 300);
        return ticket;
    }

    public WechatOpenBean authCode(String code, String appid) {

        AdminCompanyWechat adminCompanyWechat = adminCompanyWechatService.lambdaQuery().eq(AdminCompanyWechat::getAppletAppid, appid).one();

        try {
            WxMaJscode2SessionResult wxMaJscode2SessionResult = this.getMaService(adminCompanyWechat.getCompanyWechatId()).jsCode2SessionInfo(code);
            log.info("【微信授权response】:{}",JSONObject.toJSONString(wxMaJscode2SessionResult));
            WechatOpenBean bean = new WechatOpenBean();
            bean.setOpenid(wxMaJscode2SessionResult.getOpenid());
            bean.setUnionid(wxMaJscode2SessionResult.getUnionid());
            bean.setSessionKey(wxMaJscode2SessionResult.getSessionKey());
            bean.setPubAppId(adminCompanyWechat.getPubAppId());
            bean.setAppModuleJson(adminCompanyWechat.getAppModuleJson());
            return bean;
        } catch (WxErrorException e) {
            log.error("【微信授权失败】",e);
            throw new RemoteServiceException("授权失败，请联系相关人员");
        }
    }

    public String paymentfkmWebsit(String id, BigDecimal payment, String profitSharingFlag, String ip, String configId, String authCode, String source) {

        WxPayService payService = this.getPayWebstiService(configId,source);

        if (payService == null)
            throw new RemoteServiceException("未查到支付配置");

        WxPayMicropayRequest request = new WxPayMicropayRequest();
        //request.setDeviceInfo(worker.getWorkerId());
        request.setBody("售修宝费用");
        request.setOutTradeNo(id);
        request.setTotalFee(payment.multiply(new BigDecimal("100")).intValue());
        request.setSpbillCreateIp(ip);
        request.setAuthCode(authCode);
        request.setProfitSharing(profitSharingFlag); // 分账标记 Y=分账 N=不分账

        WxPayMicropayResult payResult = null;
        try {
            payResult = payService.micropay(request);
            log.info("商户扫码支付生成订单响应: {}", payResult);
        } catch (WxPayException e) {
            log.error("商户扫码支付失败: {}", payResult);
            throw new RemoteServiceException("扫码支付失败,请检查二维码是否正确");
        }
        if (payResult == null || WxPayConstants.ResultCode.FAIL.equals(payResult.getReturnCode())) {
            throw new RemoteServiceException("扫码支付失败,请检查二维码是否正确");
        }
        //记录流水

        AdminCompanyWechatPayConfig adminCompanyWechatPayConfig = adminCompanyWechatPayConfigService.getById(configId);
        this.addPayWebsitRecord(adminCompanyWechatPayConfig,payment,"",payResult.getSubOpenid(),ip,payResult.getTradeType(),id,payResult.getTransactionId());
        return payResult.getTransactionId();
    }
}
