Corporate Payment

Dolphin Elf : https://mgo.whhtjl.com

I believe you have found various materials on the Internet and read various documents. I will not repeat the whole process. If you have any doubts, you can check the details on the WeChat open platform. Web address: https:// pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2

Not much nonsense, just go to the code:

The SpringBoot and Maven project that I use for the back end here, the code is as follows:

<!--公众号(包括订阅号和服务号) -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-mp</artifactId>
	<version>2.7.0</version>
</dependency>
<!--微信支付 -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-pay</artifactId>
	<version>3.0.0</version>
</dependency>

Configure related information in application.properties

WeChat APP payment requires a certificate. You can go to the WeChat open platform to configure and download it and put it in the resources directory. You can directly import it with classpath:xxxxxx.p12

#微信支付
wx.pay.appId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.appSecret=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchKey=XXXXXXXXXXXXXXXXXXXXX
wx.pay.keyPath=classpath:apiclient_cert.p12
wx.pay.tradeType=APP
#微信公众号
wx.mp.appId=XXXXXXXXXXXXXXXXXXXX
wx.mp.appSecret=XXXXXXXXXXXXXXXXXXXXXXXX

Need to get user authorization first, the backend will get the openId and store it in the session, and then get the openId from the session when the payment is transferred


			let openId = uni.getStorageSync('openId');
			if (openId) {
				//去提现
				uni.navigateTo({
					url: 'canwithdrawmoney'
				});
			} else {
				if (this.isWeiXinBrowser()) {
					window.location.href = getApp().globalData.BaseUrl + '/thirdPartLogin/jswx/wxlogin?state=2';
					return;
				} else {
					uni.showToast({
						title: '请前往XXXXXXXXXXX微信公众号提现,如有疑问,请联系客服!',
						icon: 'none',
						duration: 3000
					});
					return;
				}
			}
		

Add the following content in the configuration file:

wx.mp.oauth2redirectUri=XXXXXXXXXXXXXXXXXXXXXXXX
wx.mp.oauth2WdmUri=XXXXXXXXXXXXXXXXXXXXX

Create a control layer

package com.ltf.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.ltf.common.CacheConstans;
import com.ltf.config.SinaWebProperties;
import com.ltf.config.WeChatAppletProperties;
import com.ltf.config.WeChatMpProperties;
import com.ltf.entity.UserProfile;
import com.ltf.service.UserProfileService;
import com.ltf.utils.HttpRequestUtil;
import com.ltf.utils.WebUtils;
import com.qq.connect.QQConnectException;
import com.qq.connect.api.OpenID;
import com.qq.connect.api.qzone.UserInfo;
import com.qq.connect.javabeans.qzone.UserInfoBean;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import weibo4j.Oauth;
import weibo4j.Users;
import weibo4j.http.AccessToken;
import weibo4j.model.User;
import weibo4j.model.WeiboException;

/**
 * 第三方登录控制层
 * @author xhz
 *
 */
@Controller
@RequestMapping("/thirdPartLogin")
public class ThirdPartLoginController extends BaseController {

	private static final Logger logger = LoggerFactory
			.getLogger(ThirdPartLoginController.class);
	@Autowired
	private UserProfileService userProfileService;

	@Autowired
	private WeChatAppletProperties weChatAppletProperties;

	@Autowired
	private  WxMpService wxJsMpService;
	@Autowired
	private WeChatMpProperties wxMpProperties;
	@Autowired
	private SinaWebProperties sinaWebProperties;

	/**
	 * jswx 请求授权地址转发
	 * @param response
	 * @throws IOException 
	 */
	@RequestMapping(path="/jswx/wxlogin", method=RequestMethod.GET)
	@ResponseBody
	public void wxRdLogin(HttpServletRequest request,HttpServletResponse response,
			@RequestParam("state") String state) throws IOException {
		if(state!=null&&state.equals("2")) {
			String redirectURI=wxJsMpService.oauth2buildAuthorizationUrl(wxMpProperties.getRedirectURI(),"snsapi_base",state);
			response.setContentType("text/html;charset=UTF-8");
			response.sendRedirect(redirectURI);
		}
	}

	/**
	 * jswx 授权登陆回调地址
	 * @param request
	 * @param response
	 * @param code
	 * @return
	 */
	@SuppressWarnings("static-access")
	@RequestMapping(path="/jswx/login", method=RequestMethod.GET)
	@ResponseBody
	public JSONObject jsWxLogin(HttpServletRequest request,HttpServletResponse response,
			@RequestParam("code") String code,@RequestParam("state") String state) {
		Map<String,Object> map=new HashMap<String,Object>();
		if(state!=null&& state.equals("2")) {
			String resRdmUrl= wxMpProperties.getOauth2WdmUri()+"?";
			try {
				WxMpOAuth2AccessToken oauth2AccessToken = wxJsMpService.oauth2getAccessToken(code);
				request.getSession().setAttribute("weixinOauth2AccessToken", oauth2AccessToken);//用于支付等安全校验
				map.put("openId",oauth2AccessToken.getOpenId());
				resRdmUrl+=this.buildQuery(200, "登陆成功!", map);
			} catch (WxErrorException e) {
				resRdmUrl+=this.buildQuery(500, "登录失败!"+e.getMessage(), map);
			}
			try {
				response.setContentType("text/html;charset=UTF-8");
				response.sendRedirect(resRdmUrl);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}
		return null;
	}

}

Front-end page receives openId

onLoad(option) {
		if (this.isWeiXinBrowser()) {
			if (option != undefined && option.code == 200) {
				uni.setStorageSync('openId', option.openId);
			}
		}
},
methods: {
        //判断是否在微信浏览器,true:是
		isWeiXinBrowser() {
			// window.navigator.userAgent属性包含了浏览器类型、版本、操作系统类型、浏览器引擎类型等信息,这个属性可以用来判断浏览器类型
			let ua = window.navigator.userAgent.toLowerCase();
			// 通过正则表达式匹配ua中是否含有MicroMessenger字符串
			if (ua.match(/MicroMessenger/i) == 'micromessenger') {
				return true;
			} else {
				return false;
			}
		}
}

Create entity class

package com.ltf.config;
 
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
/**
 * 微信支付商户基本信息
 * @author xhz
 *
 */
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WeChatPayProperties {
 
	/**
	 * appId
	 */
	private String appId;
	/**
	 * 公众平台密钥
	 */
	private String appSecret;
	/**
	 * 商户号
	 */
	private String mchId;
	/**
	 * 商户密钥
	 */
	private String mchKey;
	/**
	 * 证书
	 */
	private String keyPath;
	/**
	 * 交易类型
	 * <pre>
	 * JSAPI--公众号支付
	 * NATIVE--原生扫码支付
	 * APP--app支付
	 * </pre>
	 */
	private String tradeType;
 
	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}
 
}

Create a control layer

package com.ltf.controller;

import java.math.BigDecimal;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ltf.cache.CacheUtil;
import com.ltf.config.WeChatPayProperties;
import com.ltf.dao.AccountDetailsDao;
import com.ltf.dao.PopulistDao;
import com.ltf.entity.AccountDetails;
import com.ltf.entity.Populist;
import com.ltf.entity.User;
import com.ltf.utils.SingletonLoginUtils;
import com.ltf.utils.StringUtils;
import com.ltf.utils.WebUtils;

/**
 * 微信提现
 * @author xhz
 *
 */
@RestController
@RequestMapping(value = "/api/client/withdraw/")
public class WeChatWithdrawController extends BaseController{

	private static final Logger logger = LoggerFactory
			.getLogger(WeChatWithdrawController.class);

	@Autowired
	private WxPayService wxPayService;
	@Autowired
	private WeChatPayProperties weChatPayProperties;
	@Autowired
	private PopulistDao populistDao;
	@Autowired
	private AccountDetailsDao accountDetailsDao;

	/**
	 * 微信提现
	 * @return
	 */
	@SuppressWarnings("static-access")
	@PostMapping(value = "weChatWithdraw")
	public JSONObject refund(@RequestParam("mobileCode") String mobileCode,@RequestParam("withdrawalAmount") String withdrawalAmount,HttpServletRequest request) {
		try {
			User user=SingletonLoginUtils.getLoginUser(request);
			if(user!=null){
				if(user.getIsAvailable()==2){
					return this.formatJSON(500, "抱歉,冻结状态下无法提现!", null);
				}else{
					if(user.getMobile()!=null&&!"".equals(user.getMobile().trim())){
						// 从缓存提取手机验证码
						String mobileCodeNum = (String) CacheUtil.get(user.getMobile()+ "_mobileCodeNum_withdrawMoney");
						if (!mobileCode.equals(mobileCodeNum) || mobileCodeNum == null) {
							return this.formatJSON(500, "请填写正确的验证码!", null);
						}else{
							if(withdrawalAmount!=null&&!"".equals(withdrawalAmount.trim())){
								EntPayRequest entPayRequest = new EntPayRequest();
								entPayRequest.setAppid(weChatPayProperties.getAppId());
								entPayRequest.setMchId(weChatPayProperties.getMchId());
								entPayRequest.setPartnerTradeNo(StringUtils.getOrderNo());
								if(null!=request.getSession().getAttribute("weixinOauth2AccessTokenForWithdrawmoney")){
									WxMpOAuth2AccessToken oauth2AccessToken=(WxMpOAuth2AccessToken) request.getSession().getAttribute("weixinOauth2AccessTokenForWithdrawmoney");
									entPayRequest.setOpenid(oauth2AccessToken.getOpenId());
								}
								entPayRequest.setCheckName("NO_CHECK");
								entPayRequest.setAmount(yuanToFee(new BigDecimal(withdrawalAmount)));
								entPayRequest.setDescription("微信提现");
								entPayRequest.setSpbillCreateIp( WebUtils.getIpAddr(request));
								EntPayResult entPayResult = null;
								try {
									entPayResult = wxPayService.getEntPayService().entPay(entPayRequest);
									logger.info("entPayResult : " + entPayResult);
									//退款成功之后将用户可提现金额-
									Populist populist=new Populist();
									populist.setUserId(user.getId());
									populist.setWithdrawalAmountFlag(2);//1+;2-
									populist.setWithdrawalAmount(new BigDecimal(withdrawalAmount));
									//populist.setSettledMoneyFlag(1);//1+;2-
									//populist.setSettledMoney(new BigDecimal(withdrawalAmount));
									Integer res1=populistDao.updatePopulistInfo(populist);
									if(res1<1){
										return this.formatJSON(500, "推广员的收益信息修改失败!", null);
									}
									//添加账户明细
									AccountDetails accountDetails=new AccountDetails();
									accountDetails.setAddTime(new Date());
									accountDetails.setDetailsName("提现");
									accountDetails.setMoney(new BigDecimal(withdrawalAmount).negate());//取相反数
									accountDetails.setUserId(user.getId());
									Integer res2=accountDetailsDao.addAccountDetails(accountDetails);
									if(res2<1){
										return this.formatJSON(500, "用户的账户明细添加失败!", null);
									}
									return this.formatJSON(200, "提现成功!", null);
								} catch (WxPayException e) {
									return this.formatJSON(500, "企业微信付款失败,返回报文:"+e.getReturnMsg() + ":" + e.getErrCodeDes(), null);
								}
							}else{
								return this.formatJSON(500, "请填写提现金额!", null);
							}							
						}
					}else{
						return this.formatJSON(500, "请先绑定手机号!", null);
					}
				}
			}else{
				return this.formatJSON(500, "登录状态已失效,请重新登录!", null);
			}
		} catch (Exception e) {
			logger.error("微信退款接口错误信息= {}", e);
			return this.formatJSON(500, "微信退款接口出现异常!", null);
		}
	}

	/**
	 * 1块钱转为 100 分
	 * 元转分
	 *
	 * @param bigDecimal 钱数目
	 * @return 分
	 */
	private int yuanToFee(BigDecimal bigDecimal) {
		return bigDecimal.multiply(new BigDecimal(100)).intValue();
	}

}

 

Guess you like

Origin blog.csdn.net/qq_35393693/article/details/107383074