微信native支付生成二维码、回调通知、根据交易单号查询

生成二维码、根据交易单号查询

import com.pwh.common.po.WePay;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByIdRequest;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Data
@ConfigurationProperties("pwh.pay")
public class WePayUtils {
	/** 商户号 */
	private String merchantId;
	/** 商户API私钥路径 */
	private String privateKeyPath;
	/** 商户证书序列号 */
	private String merchantSerialNumber;
	/** 商户APIV3密钥 */
	private String apiV3Key;
	// 使用自动更新平台证书的RSA配置
	
	/**
	 * Native支付下单,获取支付地址
	 * @param wePay 传递的实体
	 * @return 支付地址,前端用于生成支付二维码
	 */
	public String nativePay(WePay wePay){
		Config config =
				new RSAAutoCertificateConfig.Builder()
						.merchantId(merchantId) // 商户号
						.privateKeyFromPath(privateKeyPath)  // API证书地址
						.merchantSerialNumber(merchantSerialNumber) // API证书序列号
						.apiV3Key(apiV3Key) // API密匙
						.build();
		// 构建service
		NativePayService service = new NativePayService.Builder().config(config).build();
		
		PrepayRequest request = new PrepayRequest();
		Amount amount = new Amount();
		amount.setTotal(wePay.getTotal()); // 金额
		request.setAmount(amount);
		request.setAppid("wx19b1a85010ddeaa2"); // 应用ID
		request.setMchid(merchantId);  // 商户号
		request.setDescription(wePay.getDescription());  // 商品描述
		request.setNotifyUrl("https://58aaae17.r10.cpolar.top/notifyresult");  // 支付成功的回调地址
		// 生成模拟系统内部订单号(yyyyMMddHHmmssSSS)
		request.setOutTradeNo(wePay.getOutTradeNo());  // 自己后端的唯一订单号,此处使用时间模拟
		// 调用下单方法,得到应答
		try {
			// 发送请求
			PrepayResponse response = service.prepay(request);
			// 使用微信扫描 code_url 对应的二维码,即可体验Native支付
			log.info("生成的二维码地址是:{}",response.getCodeUrl());
			// 将支付地址返回
			return response.getCodeUrl();
		}catch (Exception e){
			log.info("返回的错误信息:{}",e.toString());
			return e.getMessage();
		}
	}
	
	/**
	 * 手动查询订单支付状态
	 * @throws Exception
	 */
	public void QueryOrder(String transactionId) throws Exception {
		Config config =
				new RSAAutoCertificateConfig.Builder()
						.merchantId(merchantId) // 商户号
						.privateKeyFromPath(privateKeyPath)  // API证书地址
						.merchantSerialNumber(merchantSerialNumber) // API证书序列号
						.apiV3Key(apiV3Key) // API密匙
						.build();
		// 构建service
		NativePayService service = new NativePayService.Builder().config(config).build();
		QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
		queryRequest.setMchid(merchantId);
		queryRequest.setTransactionId("商户单号");
		try {
			Transaction result = service.queryOrderById(queryRequest);
			log.info("订单状态: {}", result.getTradeState());
		} catch (ServiceException e) {
			// API返回失败, 例如ORDER_NOT_EXISTS
			System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
			System.out.printf("reponse body=[%s]\n", e.getResponseBody());
		}
	}
}

WePay实体类

import lombok.Data;

import java.io.Serializable;

/**
 * 微信支付
 */
@Data
public class WePay implements Serializable {
	/**
	 * 订单金额
	 */
	private Integer total;
	/**
	 * 商品名称
	 */
	private String description;
	/**
	 * 订单号
	 */
	private String outTradeNo;
}

回调通知

public Map<String ,String> notifyNative(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Map<String, String> res = null;
		// 获取请求体原内容(此时获取的数据是加密的)
		BufferedReader reader = request.getReader();
		StringBuilder requestBody = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			requestBody.append(line);
		}
		
		// 获取请求携带的数据,构造参数
		RequestParam requestParam = new RequestParam.Builder()
				.serialNumber(request.getHeader("Wechatpay-Serial")) // 微信支付平台证书的序列号
				.nonce(request.getHeader("Wechatpay-Nonce")) // 签名中的随机数
				.signature(request.getHeader("Wechatpay-Signature"))  // 应答的微信支付签名
				.timestamp(request.getHeader("Wechatpay-Timestamp")) // 签名中的时间戳
				.body(requestBody.toString()) // 请求体内容(原始内容,不要解析)
				.build();
		
		// 初始化RSAAutoCertificateConfig
		NotificationConfig config = new RSAAutoCertificateConfig.Builder()
				.merchantId() // 商户号
				// API证书路径,路径自己调试,能找到就行(NativeUtil为自定义工具类)
				.privateKeyFromPath("")
				.merchantSerialNumber("50") // 证书序列号
				.apiV3Key("") // APIV3密匙
				.build();
		// 初始化 NotificationParser
		NotificationParser parser = new NotificationParser(config);
		// 解析为Transaction对象(解密数据)
		Transaction transaction = null;
		try {
			transaction = parser.parse(requestParam, Transaction.class);
			// 获取支付单号
			log.info("支付成功,回调信息:{}", transaction);
			// 打印其中的"微信支付单号"字段,可用于查单操作
			log.info("微信支付单号:{}", transaction.getTransactionId());
		} catch (Exception e) {
			res.put("code","FAIL");
			res.put("message","失败");
			return res;
		}
		return res;
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值