微信小程序支付流程

WxPayController

package com.example.demo.com.example.wxPay.controller;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

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.RestController;

import com.example.demo.com.example.task.AjaxResult;
import com.example.demo.com.example.task.IpUtils;
import com.example.demo.com.example.wxPay.entity.RechargeOrder;
import com.example.demo.com.example.wxPay.entity.WxPayBean;
import com.example.demo.com.example.wxPay.entity.WxPayMiniAppPay;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.UnifiedOrderModel;

/**
 * 微信支付
 * 
 * @author Administrator
 *
 */
@RestController
@RequestMapping("wxPay")
public class WxPayController extends AbstractWxPayApiController {
	// 获取微信支付配置
	@Autowired
	WxPayBean wxPayBean;
	private final Logger log = LoggerFactory.getLogger(this.getClass());
//	回调地址
	private String notifyUrl;
//	退款回调地址
//	private String refundNotifyUrl;

	@Override
	public WxPayApiConfig getApiConfig() {
		WxPayApiConfig apiConfig;

		try {
			apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
		} catch (Exception e) {
			apiConfig = WxPayApiConfig.builder().appId(wxPayBean.getAppId()).mchId(wxPayBean.getMchId())
					.partnerKey(wxPayBean.getPartnerKey()).certPath(wxPayBean.getCertPath())
					.domain(wxPayBean.getDomain()).build();
		}
		notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
//		refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
		return apiConfig;
	}

	/**
	 * 微信小程序支付
	 * 
	 */
	@PostMapping("miniAppPay")
	public AjaxResult miniAppPay(@Valid WxPayMiniAppPay wxPayMiniAppPay) {
		// 获取openId一般情况下用户登录的时候openId是和用户关联的 所以openId可以通过当前的userId去查询openId
		String openId = "用户的openId";
		String ip = IpUtils.getHostIp();
		WxPayApiConfig wxPayApiConfig = getApiConfig();
//		默认金额
		BigDecimal orderPrice = new BigDecimal("1");
//		附加参数
		String attach = "";
//		商品描述
		String body = "";
//		商户订单号例如EE123456789
		String out_trade_no = wxPayMiniAppPay.getOrderNum();
//		判断是否为充值订单类型
		String orderType = out_trade_no.subSequence(0, 2).toString();
		if (orderType.equals("EE")) {
//          根据订单号查询订单我这里就直接初始化实体了
//          RechargeOrder rechargeOrder = rechargeOrderService.selectByOrderId(out_trade_no); 
			RechargeOrder rechargeOrder = new RechargeOrder();
//			订单和支付状态非初始化状态即不允许支付
			if (rechargeOrder == null || rechargeOrder.getOrderStatus() != 1 || rechargeOrder.getPayStatus() != 1) {
				return AjaxResult.error("订单不存在或不允许支付");
			}
//			订单描述
			body = "充值订单";
//			订单金额单位是元
			orderPrice = rechargeOrder.getOrderPrice();
		} else {
			return AjaxResult.error("订单类型不存在");
		}
		Map<String, String> params = UnifiedOrderModel.builder().appid(wxPayApiConfig.getAppId())
				.mch_id(wxPayApiConfig.getMchId()).nonce_str(WxPayKit.generateStr()).body(body).attach(attach)
				.out_trade_no(out_trade_no)
				// 注意 微信单位是分 我的数据库存的是元 需要转换
				.total_fee(String.valueOf(orderPrice.multiply(new BigDecimal("100")).intValue())).spbill_create_ip(ip)
				.notify_url(notifyUrl).trade_type(TradeType.JSAPI.getTradeType()).openid(openId).build()
				.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
		String xmlResult = WxPayApi.pushOrder(false, params);
		Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
		String returnCode = result.get("return_code");
		String returnMsg = result.get("return_msg");
		if (!WxPayKit.codeIsOk(returnCode)) {
			return AjaxResult.error(returnMsg);
		}
		String resultCode = result.get("result_code");
		if (!WxPayKit.codeIsOk(resultCode)) {
			return AjaxResult.error(returnMsg);
		}
		// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
		String prepayId = result.get("prepay_id");
		Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
				wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
//		String jsonStr = JSON.toJSONString(packageParams);
		log.info("小程序支付统一下单返回参数:" + packageParams.toString());
		return AjaxResult.success(packageParams);
	}

	/**
	 * 退款通知
	 */
	@RequestMapping(value = "/refundNotify")
	public String refundNotify(HttpServletRequest request) {
		String xmlMsg = HttpKit.readData(request);
		log.info("退款通知=" + xmlMsg);
		Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
		String returnCode = params.get("return_code");
		// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
		if (WxPayKit.codeIsOk(returnCode)) {
			String reqInfo = params.get("req_info");
			String decryptData = WxPayKit.decryptData(reqInfo, getApiConfig().getPartnerKey());
			log.info("退款通知解密后的数据=" + decryptData);

			// 这里是处理订单信息,例如修改订单状态啥的逻辑,自己编辑

			// 发送通知等
			Map<String, String> xml = new HashMap<String, String>(2);
			xml.put("return_code", "SUCCESS");
			xml.put("return_msg", "OK");
			return WxPayKit.toXml(xml);
		}
		return null;
	}

	/**
	 * 支付回调异步通知
	 */
	@RequestMapping(value = "/payNotify")
	public String payNotify(HttpServletRequest request) {
		String xmlMsg = HttpKit.readData(request);
		log.info("支付回调通知=" + xmlMsg);
		Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
		// 支付回调的code
		String returnCode = params.get("return_code");
		// 支付时间
		String payTime = params.get("time_end");

		// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
		// 注意此处签名方式需与统一下单的签名类型一致
		if (WxPayKit.verifyNotify(params, getApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
			if (WxPayKit.codeIsOk(returnCode)) {
				String resultCode = params.get("result_code");
//				resultCode为SUCCESS时才代表支付成功
				if (WxPayKit.codeIsOk(resultCode)) {
					String orderId = params.get("out_trade_no");
//					支付流水
					String transactionId = params.get("transaction_id");

//					订单金额(分):将分转化为BigDecimal 元
					BigDecimal totalFee = new BigDecimal(params.get("total_fee")).divide(new BigDecimal("100"));
					// 更新订单信息
//					判断是否为充值订单
					String orderType = orderId.subSequence(0, 2).toString();
					if (orderType.equals("EE")) {
//						RechargeOrder rechargeOrder = rechargeOrderService.selectByOrderId(orderId);
						RechargeOrder rechargeOrder = new RechargeOrder();
//						判断订单是否为初始化状态,支付金额一致
						if (rechargeOrder != null
								&& (rechargeOrder.getOrderStatus() == 1 || rechargeOrder.getOrderStatus() == 4)
								&& rechargeOrder.getPayStatus() == 1
								&& totalFee.compareTo(rechargeOrder.getOrderPrice()) == 0) {
//							修改支付成功状态
							try {
//                              rechargeOrderService.paySuccess(orderId, transactionId, 1);
								// 支付成功之后做的处理 我就不贴出来了 一般就是记录一下流水啊 修改订单状态的逻辑
							} catch (Exception e) {
								log.error("充值订单支付回调异常", e);
							}
						}
					}
				}
				Map<String, String> xml = new HashMap<String, String>(2);
				xml.put("return_code", "SUCCESS");
				xml.put("return_msg", "OK");
				return WxPayKit.toXml(xml);
			}
		}
		return null;
	}

	public static void main(String[] args) {
		BigDecimal totalFee = new BigDecimal("2536").divide(new BigDecimal("100"));
		System.out.println(totalFee);
	}

}

WxPayInterceptor 微信支付拦截器

package com.example.demo.com.example.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import com.example.demo.com.example.wxPay.controller.AbstractWxPayApiController;
import com.ijpay.wxpay.WxPayApiConfigKit;

/**
 * @ClassName: WxPayInterceptor
 * @Description: 微信支付拦截器
 * @author wsj
 * @date 2020年11月4日
 *
 */
public class WxPayInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object handler) {
		if (HandlerMethod.class.equals(handler.getClass())) {
			HandlerMethod method = (HandlerMethod) handler;
			Object controller = method.getBean();
			if (!(controller instanceof AbstractWxPayApiController)) {
				throw new RuntimeException("控制器需要继承 AbstractWxPayApiController");
			}
			WxPayApiConfigKit.setThreadLocalWxPayApiConfig(((AbstractWxPayApiController) controller).getApiConfig());
			return true;
		}
		return false;
	}
}

 

 

AbstractWxPayApiController

package com.example.demo.com.example.wxPay.controller;

import com.ijpay.wxpay.WxPayApiConfig;

/**
 * @author Javen
 */
public abstract class AbstractWxPayApiController {
	/**
	 * 获取微信支付配置
	 *
	 * @return {@link WxPayApiConfig} 微信支付配置
	 */
	public abstract WxPayApiConfig getApiConfig();
}

三个实体bean

package com.example.demo.com.example.wxPay.entity;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 充值订单
 * 
 * @author Administrator
 *
 */
public class RechargeOrder {
	/**
	 * 订单号
	 */
	private String orderId;

	/**
	 * 用户id
	 */
	private Integer userId;

	/**
	 * 订单状态1待处理,2已完成,3处理失败,4已取消,5退款
	 */
	private Integer orderStatus;

	/**
	 * 订单金额
	 */
	private BigDecimal orderPrice;

	/**
	 * 能源币数量
	 */
	private Integer balance;

	/**
	 * 创建时间
	 */
	private Date createTime;

	/**
	 * 支付状态1待支付2支付成功
	 */
	private Integer payStatus;

	/**
	 * 订单支付类型1微信2支付宝
	 */
	private Integer payType;

	/**
	 * 支付时间
	 */
	private Date payTime;

	/**
	 * 订单支付流水号
	 */
	private String outTradeNo;

	/** 0未删除,1已删除 */
	private Integer isDelete;

	public String getOrderId() {
		return orderId;
	}

	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public Integer getOrderStatus() {
		return orderStatus;
	}

	public void setOrderStatus(Integer orderStatus) {
		this.orderStatus = orderStatus;
	}

	public BigDecimal getOrderPrice() {
		return orderPrice;
	}

	public void setOrderPrice(BigDecimal orderPrice) {
		this.orderPrice = orderPrice;
	}

	public Integer getBalance() {
		return balance;
	}

	public void setBalance(Integer balance) {
		this.balance = balance;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public Integer getPayStatus() {
		return payStatus;
	}

	public void setPayStatus(Integer payStatus) {
		this.payStatus = payStatus;
	}

	public Integer getPayType() {
		return payType;
	}

	public void setPayType(Integer payType) {
		this.payType = payType;
	}

	public Date getPayTime() {
		return payTime;
	}

	public void setPayTime(Date payTime) {
		this.payTime = payTime;
	}

	public String getOutTradeNo() {
		return outTradeNo;
	}

	public void setOutTradeNo(String outTradeNo) {
		this.outTradeNo = outTradeNo;
	}

	public Integer getIsDelete() {
		return isDelete;
	}

	public void setIsDelete(Integer isDelete) {
		this.isDelete = isDelete;
	}

}



package com.example.demo.com.example.wxPay.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @ClassName: WxPayBean
 * @Description: 微信配置 Bean
 * @author wsj
 * @date 2020年11月4日
 *
 */
@Component
@PropertySource("classpath:/wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
public class WxPayBean {
	private String appId;
	private String appSecret;
	private String mchId;
	private String partnerKey;
	private String certPath;
	private String domain;

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getAppSecret() {
		return appSecret;
	}

	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}

	public String getMchId() {
		return mchId;
	}

	public void setMchId(String mchId) {
		this.mchId = mchId;
	}

	public String getPartnerKey() {
		return partnerKey;
	}

	public void setPartnerKey(String partnerKey) {
		this.partnerKey = partnerKey;
	}

	public String getCertPath() {
		return certPath;
	}

	public void setCertPath(String certPath) {
		this.certPath = certPath;
	}

	public String getDomain() {
		return domain;
	}

	public void setDomain(String domain) {
		this.domain = domain;
	}

	@Override
	public String toString() {
		return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
				+ partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
	}
}



package com.example.demo.com.example.wxPay.entity;

import javax.validation.constraints.NotNull;

public class WxPayMiniAppPay {
	@NotNull(message = "请输入正确的订单号")
	private String OrderNum;

	// 支付类型1微信2支付宝
	private Integer type = 1;

	public String getOrderNum() {
		return OrderNum;
	}

	public void setOrderNum(String orderNum) {
		OrderNum = orderNum;
	}

	public Integer getType() {
		return type;
	}

	public void setType(Integer type) {
		this.type = type;
	}

}

 

wxpay.properties

#应用编号
wxpay.appId=wxc*****
#应用秘钥
wxpay.appSecret=****
#商户号
wxpay.mchId=****
#微信的商户秘钥key
wxpay.partnerKey=****
# API 证书中的 p12安装目录
wxpay.certPath=/root/payCert/wechat/apiclient_cert.p12
#应用域名,回调中会使用此参数
wxpay.domain=https://ceshi.wxPay/ceshi

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </dependency>
        
        <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.15</version>
		</dependency>
		
		<!-- IJPay微信支付 https://gitee.com/javen205/IJPay -->
		<dependency>
				<groupId>com.github.javen205</groupId>
				<artifactId>IJPay-WxPay</artifactId>
				<version>2.7.0</version>
		</dependency>
		<dependency>
		    <groupId>javax.validation</groupId>
		    <artifactId>validation-api</artifactId>
        </dependency>
        
           <dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
	     </dependency>
        
		<dependency>
	       <groupId>org.springframework.boot</groupId>
	       <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
			
		<dependency>
		        <groupId>org.springframework.boot</groupId>
			    <artifactId>spring-boot-starter</artifactId>
		 </dependency>
 
		 <dependency>
				     <groupId>org.springframework.boot</groupId>
					 <artifactId>spring-boot-starter-test</artifactId>
			         <scope>test</scope>
		</dependency>

			
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>

        </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值