SpringBoot微信支付WechatPayV3

1、获取appid、秘钥、申请证书

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml

wechat:
  miniapp:
    configs:
      - appid: wx68fd8d5ac14cc768
        secret: 64fcfbd73508e7e10e03b72770fe166c
        token: #微信小程序消息服务器配置的token
        aesKey: #微信小程序消息服务器配置的EncodingAESKey
        msgDataFormat: JSON
  pay:
    appId: wx68***cc768
    mchId: 16***4010
    keyPath: ./WechatPayMerchantPrivateKey.pem
    certPath: ./WechatPayMerchantCert.pem
    platformCertPath: ./WechatPayPlatformCert.pem
    apiKey3: mETKpE***3TB8yaLa
    domain: https:***.cn
    serialNo: 3C5B355***EA8755E
    notifyURL: https://***/order/wechatpay/notify/
@ConfigurationProperties(prefix = "wechat.pay")
public class WechatPayV3Properties {
   private String appId;
   private String keyPath;
   private String certPath;
   private String platformCertPath;
   private String mchId;
   private String apiKey3;
   private String domain;
   private String serialNo;
   private String notifyURL;
}

2、服务类,主要用于获取预支付id和签名,微信支付前需要拿到预支付id(prepayId),想要成功拉起支付要对预支付id进行签名才能支付。

@Slf4j
@Configuration
@AllArgsConstructor
@EnableConfigurationProperties(WechatPayV3Properties.class)
public class WechatPayJsApiServiceClient {
	private final WechatPayV3Properties wechatPayV3Properties;

	/**
	 * 获取小程序支付服务
	 */
	private JsapiService getAppService() {
		// 初始化商户配置
		RSAConfig config =
			new RSAConfig.Builder()
				.merchantId(wechatPayV3Properties.getMchId())
				// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
				.privateKeyFromPath(wechatPayV3Properties.getKeyPath())
				.merchantSerialNumber(wechatPayV3Properties.getSerialNo())
				.wechatPayCertificatesFromPath(wechatPayV3Properties.getCertPath(), wechatPayV3Properties.getPlatformCertPath())
				.build();

		// 初始化服务
		return new JsapiService.Builder().config(config).build();
	}

	/**
	 * 小程序支付下单
	 *
	 * @param desc        商品描述
	 * @param outTradeNo  交易订单号
	 * @param openId      支付者微信OpenId
	 * @param totalAmount 商品总金额(单位分)
	 */
	public PrepayResponse prepay(String desc, String outTradeNo, String openId, Integer totalAmount) {

		PrepayRequest request = new PrepayRequest();
		request.setAppid(wechatPayV3Properties.getAppId());
		request.setMchid(wechatPayV3Properties.getMchId());
		request.setDescription(desc);
		request.setOutTradeNo(outTradeNo);
		request.setNotifyUrl(wechatPayV3Properties.getNotifyURL());
		Amount amount = new Amount();
		amount.setTotal(totalAmount);
		request.setAmount(amount);
		Payer payer = new Payer();
		payer.setOpenid(openId);
		request.setPayer(payer);
//		request.setTimeExpire(); 订单失效时间
//		request.setSupportFapiao(); 传入true时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效。

		// 调用接口
		return getAppService().prepay(request);
	}

	/**
	 * 微信支付订单号查询订单
	 */
	public Transaction queryOrderById() {

		QueryOrderByIdRequest request = new QueryOrderByIdRequest();
		// 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
		// 调用接口
		return getAppService().queryOrderById(request);
	}

	/**
	 * 商户订单号查询订单
	 */
	public Transaction queryOrderByOutTradeNo() {

		QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
		// 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
		// 调用接口
		return getAppService().queryOrderByOutTradeNo(request);
	}

	/**
	 * 生成微信调起支付的签名
	 * @param wechatPayPerPayId 微信预支付交易会话标识
	 */
	public Map<String, Object> sign(String wechatPayPerPayId) throws IOException {
		String privateKeyStr = IOUtil.loadStringFromPath(wechatPayV3Properties.getKeyPath());
		PrivateKey privateKey = PemUtil.loadPrivateKeyFromString(privateKeyStr);
		RSASigner rsaSigner = new RSASigner(wechatPayV3Properties.getSerialNo(), privateKey);
		Long timestamp = new Date().getTime() / 1000;

//随机数最长32,这个随机数没有其他规定,随便给一个就可以
		String nonceStr = CommonUtil.generate_random_str(32);
		String encryptStr = String.format("%s\n%s\n%s\nprepay_id=%s\n", wechatPayV3Properties.getAppId(), timestamp, nonceStr, wechatPayPerPayId);

//v3支付固定前面类型RSA
		SignatureResult signatureResult = rsaSigner.sign(encryptStr);

		Map<String, Object> data = new HashMap<>();
		data.put("appid", wechatPayV3Properties.getAppId());
		data.put("wechatPayMerchantId", wechatPayV3Properties.getMchId());
		data.put("timestamp",timestamp);
		data.put("nonceStr", nonceStr);
		data.put("sign", signatureResult.getSign());
		data.put("wechatPayPerPayId", wechatPayPerPayId);
		return data;
	}
}

3、对应订单传入预支付接口获取预支付id,传入签名接口获取签名,返回给前端

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Map<String, Object> wechatPay(WechatPayDTO wechatPayDTO) throws CallBackException {
    String wechatPayPrePayId = null;
		Map<String, Object> signData = null;
		try {
			// 创建订单(传什么看需求)
            //reseller.getName()"测试经销商"、orderDesc“充值订单”
			String goodsDesc = String.format("%s-%s", reseller.getName(), orderDesc);
//order.getPayOrderNo()随机生成的订单号,reseller.getOpenId()小程序唯一标识,order.getTotalRealAmount()实付金额
			PrepayResponse prepayResponse = wechatPayJsApiServiceClient.prepay(goodsDesc, order.getPayOrderNo(), reseller.getOpenId(), order.getTotalRealAmount());
			wechatPayPrePayId = prepayResponse.getPrepayId();

			// 生成签名
			signData = wechatPayJsApiServiceClient.sign(wechatPayPrePayId);
		} catch (Exception e) {
			log.error(e.toString());
			throw new CallBackException(BusinessResultCode.ERROR_WECHAT_ORDER_GENERATE_FAIL);
		}

		// 如果任一事务失败,触发回滚
		if (updateOrderResult == 0 | !updateBatchResult | !createChargeLogResult) {
			throw new CallBackException(ResultCode.FAILURE.getMessage());
		}

		map.put("data", signData);
		map.put("result", "success");
		return map;
}

4、前端拉起微信支付

function submitWeChatPay(orderID,payAmount,callback) {
    if (typeof WeixinJSBridge != "undefined") {
        var param = {
            orderID:orderID,
            payAmount:payAmount
        }
        httpPost(JSON.stringify(param),"http://xxxx/wechatpay/prepay",function (data, status) {
            var param = {
                "appId": data.appId,    
                "timeStamp": data.timeStamp,  
                "nonceStr": data.nonceStr,    
                "package": data.packageVal,
                "signType": data.signType,    
                "paySign": data.paySign
            }
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', param,callback);
        })
    } else {
        alert("非微信环境")
    }
}

5、微信回调接口,接口地址就是notifyURL

/**
	 * 微信支付回调
	 */
	@PostMapping("/wechatpay/notify")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "微信支付回调", notes = "")
	public R wechatPayNotify(@RequestHeader("Wechatpay-Serial") String serialNo,
							 @RequestHeader("Wechatpay-Signature") String signature,
							 @RequestHeader("Wechatpay-Timestamp") String timestamp,
							 @RequestHeader("Wechatpay-Nonce") String nonce,
							 @RequestBody String requestBody) {
		log.info("==Serial:{}", serialNo);
		log.info("==Signature:{}", signature);
		log.info("==Timestamp:{}", timestamp);
		log.info("==Nonce:{}", nonce);
		log.info("==支付回调:{}", requestBody);
		RequestParam requestParam = new RequestParam.Builder()
			.signature(signature)
			.body(requestBody)
			.serialNumber(serialNo)
			.timestamp(timestamp)
			.nonce(nonce)
			.build();

		// 初始化 NotificationParser
		RSANotificationConfig rsaNotificationConfig = new RSANotificationConfig.Builder()
			.certificatesFromPath(wechatPayV3Properties.getCertPath())
			.apiV3Key(wechatPayV3Properties.getApiKey3())
			.build();
		NotificationParser notificationParser = new NotificationParser(rsaNotificationConfig);
		// 验签并解密报文
		JSONObject decryptObject = notificationParser.parse(requestParam, JSONObject.class);
		log.info("==>wechat pay callBack :{}", decryptObject.toJSONString());
		return null;
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SpringBoot是一个开源的Java应用程序框架,用于快速构建独立的、基于生产级别的Java应用程序。它提供了许多功能和工具,可以简化开发过程并提高开发效率。而H5微信支付是指在移动端网页上使用微信支付的一种方式。下面是使用SpringBoot来实现H5微信支付的步骤: 1. 准备工作:首先,您需要拥有微信公众号或小程序账号,并开通支付功能。您还需要有自己的服务器,以接收微信支付的通知。同时,确保您已经使用了Java SpringBoot框架。 2. 配置微信支付参数:在SpringBoot项目的配置文件中,添加微信支付所需的配置参数,包括AppID、商户号、支付密钥等。这些参数可以在微信开放平台上获取。 3. 引入相关依赖:在项目的构建文件中,添加微信支付相关的依赖项,如微信支付SDK或其他相关库。这些依赖项将帮助您在代码中调用微信支付接口。 4. 创建统一下单接口:使用SpringBoot框架创建一个用于接收支付请求的接口。在该接口中,您需要获取用户的支付信息,并调用微信支付统一下单接口生成预支付订单。 5. 处理支付结果通知:创建一个用于接收微信支付结果通知的接口。在该接口中,您需要验证支付结果的合法性,并处理相应的业务逻辑。 6. 前端页面开发:在前端页面中添加微信支付的相关逻辑,包括调用微信支付接口、展示支付结果等。 总结起来,要使用SpringBoot来实现H5微信支付,您需要进行准备工作,配置微信支付参数,引入相关依赖,创建统一下单接口,处理支付结果通知,以及在前端页面中添加支付逻辑。这样就可以实现使用SpringBoot进行H5微信支付了。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值