イルカエルフ:https : //mgo.whhtjl.com
インターネットでさまざまな資料を見つけて、さまざまなドキュメントを読んだと思います。プロセス全体を繰り返すことはしません。疑問がある場合は、WeChatオープンプラットフォームで詳細を確認できます。Webアドレス:https:// pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
あまり意味がありません。コードにアクセスしてください。
ここでバックエンドに使用するSpringBootおよびMavenプロジェクトのコードは次のとおりです。
<!--公众号(包括订阅号和服务号) -->
<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>
application.propertiesで関連情報を構成します
WeChat APPの支払いには証明書が必要です。WeChatオープンプラットフォームに移動して構成し、ダウンロードしてリソースディレクトリに配置できます。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
最初にユーザー認証を取得する必要があります。バックエンドはopenIdを取得してセッションに保存し、支払いが転送されるときにセッションからopenIdを取得します
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;
}
}
次の内容を構成ファイルに追加します。
wx.mp.oauth2redirectUri=XXXXXXXXXXXXXXXXXXXXXXXX
wx.mp.oauth2WdmUri=XXXXXXXXXXXXXXXXXXXXX
コントロールレイヤーを作成する
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;
}
}
フロントエンドページが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;
}
}
}
エンティティークラスを作成する
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);
}
}
コントロールレイヤーを作成する
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();
}
}