相信大家已在网上找了各种资料,也看过了各种文档,对于整个流程我就不再重复啦,有疑惑的小伙伴可以移步微信开放平台查看详情,网页地址:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1
废话不多说,直接上代码:
uni-app前端代码:
{{vipName}}
¥
我这里后端使用的SpringBoot,Maven项目,代码如下:
com.github.binarywang
weixin-java-mp
2.7.0
com.github.binarywang
weixin-java-pay
3.0.0
在application.properties中配置相关信息
微信APP支付这块是需要证书,大家自行去微信开放平台配置下载后放入resources目录下,可直接用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
创建实体类
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;
/**
* 交易类型
*
* JSAPI--公众号支付
* NATIVE--原生扫码支付
* APP--app支付
*
*/
private String tradeType;
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this,
ToStringStyle.MULTI_LINE_STYLE);
}
}
将微信支付信息注入bean中
package com.ltf.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* 微信支付信息注入bean中
* @author xhz
*
*/
@Component
public class WeChatPayConfig {
@Autowired
private WeChatPayProperties properties;
@Bean
@ConditionalOnMissingBean
public WxPayConfig payConfig() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(this.properties.getAppId());
payConfig.setMchId(this.properties.getMchId());
payConfig.setMchKey(this.properties.getMchKey());
payConfig.setKeyPath(this.properties.getKeyPath());
payConfig.setTradeType(this.properties.getTradeType());
return payConfig;
}
@Bean
public WxPayService wxPayService(WxPayConfig payConfig) {
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
@Bean
public WxMpService wxMpService( ){
WxMpService wxMpService = new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
return wxMpService;
}
@Bean
public WxMpConfigStorage wxMpConfigStorage(){
WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();
wxMpConfigStorage.setAppId(this.properties.getAppId());
wxMpConfigStorage.setSecret(this.properties.getAppSecret());
return wxMpConfigStorage;
}
}
创建控制层
package com.ltf.controller;
import com.ltf.common.ReqChanle;
import com.ltf.config.WeChatPayProperties;
import com.ltf.dao.MemberCardOrdersDao;
import com.ltf.entity.MemberCardOrders;
import com.ltf.service.MemberCardOrdersService;
import com.ltf.service.MemberCardTrxorderDetailService;
import com.ltf.utils.HttpRequestUtil;
import com.ltf.utils.SingletonLoginUtils;
import com.ltf.utils.WebUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
* 微信支付
* @author xhz
*
*/
@RestController
@RequestMapping(value = "/api/client/pay/")
public class WeChatPayController extends BaseController{
private static final Logger logger = LoggerFactory
.getLogger(WeChatPayController.class);
@Autowired
private WxPayService wxPayService;
@Autowired
private WeChatPayProperties weChatPayProperties;
@Autowired
private MemberCardOrdersService memberCardOrdersService;
@Autowired
private MemberCardOrdersDao memberCardOrdersDao;
@Autowired
private MemberCardTrxorderDetailService memberCardTrxorderDetailService;
/**
* app支付
* @param request
* @param memberCardTypeId
* @param payType
* @param orderAmount
* @param memberCardTypeName
* @return
*/
@SuppressWarnings("static-access")
@GetMapping(value = "weChatPay")
@ResponseBody
public JSONObject weChatPay(
HttpServletRequest request,
@RequestParam("memberCardTypeId")String memberCardTypeId,
@RequestParam("payType")String payType,
@RequestParam("orderAmount")String orderAmount,
@RequestParam("memberCardTypeName")String memberCardTypeName) {
try {
Integer userId=SingletonLoginUtils.getLoginUserId(request);
if(userId>0){
Map sourceMap = new HashMap();
sourceMap.put("memberCardTypeId", memberCardTypeId);// 会员卡类型id
sourceMap.put("userId", userId+ "");//用户id
sourceMap.put("reqchanle", ReqChanle.APP.toString());//用户请求来源
sourceMap.put("payType", payType);// 支付类型
sourceMap.put("reqIp", WebUtils.getIpAddr(request));// 用户ip
sourceMap.put("orderAmount", orderAmount);// 订单原始金额,也是实际支付金额
sourceMap.put("memberCardTypeName", memberCardTypeName);// 会员卡类型名称
Map res = memberCardOrdersService.addTrxorder(request,sourceMap);
if(res.containsKey("msg")){
return this.formatJSON(501, "会员卡订单创建失败!", res);
}else{
/**
* 处理内部业务,校验订单等
*/
final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
//订单编号
.outTradeNo(res.get("orderNo").toString())
//订单金额
.totalFee(yuanToFee(new BigDecimal(orderAmount)))
//商品描述
.body(memberCardTypeName)
//获取本地IP
.spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())
.notifyUrl("https://你的域名/api/client/pay/weChatPayNotify")
.build();
WxPayAppOrderResult wxPayAppOrderResult =null;
try {
wxPayAppOrderResult = wxPayService.createOrder(wxPayUnifiedOrderRequest);
} catch (WxPayException e) {
e.printStackTrace();
throw new RuntimeException("微信支付调起失败!");
}
JSONObject resOrderInfo=new JSONObject();
resOrderInfo.put("appid",wxPayAppOrderResult.getAppId());
resOrderInfo.put("noncestr",wxPayAppOrderResult.getNonceStr());
resOrderInfo.put("package",wxPayAppOrderResult.getPackageValue());
resOrderInfo.put("partnerid",wxPayAppOrderResult.getPartnerId());
resOrderInfo.put("prepayid",wxPayAppOrderResult.getPrepayId());
resOrderInfo.put("timestamp",wxPayAppOrderResult.getTimeStamp());
resOrderInfo.put("sign",wxPayAppOrderResult.getSign());
res.put("data", resOrderInfo);
return this.formatJSON(200, "OK", res);}
}else{
return this.formatJSON(500, "当前登录已失效,请重新登录!",null);
}
} catch (Exception e) {
logger.error("WeChatPayController.weChatPay()----error", e);
return this.formatJSON(500, "APP内微信支付时会员卡订单创建失败!",null);
}
}
/**
* app支付返回的流
* @param xmlData
* @return
*/
@RequestMapping(value = "weChatPayNotify",method = {RequestMethod.GET,RequestMethod.POST})
public String weChatPayNotify(@RequestBody String xmlData){
try {
final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
//这里是存储我们发起支付时订单号的信息,所以取出来
MemberCardOrders memberCardOrders=new MemberCardOrders();
memberCardOrders.setOrderNo(notifyResult.getOutTradeNo());
//根据订单号查询订单
MemberCardOrders mco=memberCardOrdersDao.selectMemberCardOrdersByCondition(memberCardOrders);
//验证商户id和价格,以防止篡改金额
if(mco!=null){
if(weChatPayProperties.getMchId().equals(notifyResult.getMchId())&¬ifyResult.getTotalFee().equals(yuanToFee(mco.getSumMoney()))){
Map map=new HashMap();
map.put("sumMoney", feeToYuan(notifyResult.getTotalFee()));//订单总金额
map.put("outTradeNo", notifyResult.getTransactionId());//支付宝的交易号
map.put("orderNo", notifyResult.getOutTradeNo());//商户系统的唯一订单号
map.put("states", notifyResult.getResultCode());//交易状态
map.put("payTime", notifyResult.getTimeEnd());//支付时间
//修改会员卡订单信息
String result1=memberCardOrdersService.updateMemberCardOrderInfoForNotify(map);
if(result1.equals("error")){
return WxPayNotifyResponse.fail("修改会员卡订单信息失败!");
}
//修改会员卡订单流水信息
String result2=memberCardTrxorderDetailService.updateMemberCardTrxorderDetaiInfoForNotify(map);
if(result2.equals("error")){
return WxPayNotifyResponse.fail("修改会员卡订单流水信息失败!");
}
//成功后回调微信信息
return WxPayNotifyResponse.success("回调成功!");
}else{
return WxPayNotifyResponse.fail("商户id和价格验证不通过!");
}
}else{
return WxPayNotifyResponse.fail("订单号不存在!");
}
} catch (WxPayException e) {
logger.error("WeChatPayController.weChatPayNotify()----error", e);
return WxPayNotifyResponse.fail("APP内微信支付回调有误!");
}
}
/**
* 1块钱转为 100 分
* 元转分
*
* @param bigDecimal 钱数目
* @return 分
*/
private int yuanToFee(BigDecimal bigDecimal) {
return bigDecimal.multiply(new BigDecimal(100)).intValue();
}
/**
* 100分转为1块钱
* 分转元
*
* @param price 钱数目
* @return 元
*/
private String feeToYuan(Integer price) {
return BigDecimal.valueOf(Long.valueOf(price)).divide(new BigDecimal(100)).toString();
}
}