微信支付宝app,h5支付

微信支付

h5支付文档: https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1
参考文档地址: https://pay.weixin.qq.com/wiki/doc/api/index.html

这里用的是v2接口 ,使用的是binary-wang 工具
链接: http://binarywang.com/

准备

wx:
  pay:
    app-id: wx1231231  #appId
    mch-id: 123123123  #商户号
    mch-key: wx321323 #密钥
    key-path: classpath:/certs/xxx.p12 #证书 
  notify-url: http://192.168.2.2:2323/public/notify #支付成功回调地址
  spbill_create_ip: 101.91.219.95   #ip, 好像服务器ip和客户ip都行

pom添加依赖

<!--微信支付-->
<dependency>
  <groupId>com.github.binarywang</groupId>
  <artifactId>wx-java-pay-spring-boot-starter</artifactId>
  <version>4.1.0</version>
</dependency>

配置类

@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
	private WxPayProperties properties;

	@SneakyThrows
	@Bean
	@ConditionalOnMissingBean
	public WxPayService wxService() {
		WxPayConfig payConfig = new WxPayConfig();
		payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
		payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
		payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
		payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
		payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
		payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
		// 可以指定是否使用沙箱环境
		payConfig.setUseSandboxEnv(false);

		WxPayService wxPayService = new WxPayServiceImpl();
		wxPayService.setConfig(payConfig);
		return wxPayService;
	}
}

创建订单

	// 创建订单.
	public WxPayAppOrderResult wxPayCreateOrder(String tradeNo, BigDecimal price, String body) {
		WxPayUnifiedOrderRequest orderRequest = getWxPayUnifiedOrderRequest(body, tradeNo, price, WxPayConstants.TradeType.APP);
		try {
			log.info("生成订单参数:[{}]", orderRequest);
			return wxPayService.createOrder(orderRequest);
		} catch (WxPayException e) {
			log.error("微信支付失败!原因:", e);
			throw new IllegalArgumentException("微信支付失败!原因:" + e.getMessage());
		}
	}
    public WxPayUnifiedOrderRequest getWxPayUnifiedOrderRequest(String body, String tradeNo, BigDecimal price, String tradeType) {
		WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
		//签名类型
		orderRequest.setSignType(WxPayConstants.SignType.MD5);
		//终端IP
//		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//		assert requestAttributes != null;
//		HttpServletRequest contextRequest = requestAttributes.getRequest();
//		spbill_create_ip

//		orderRequest.setSpbillCreateIp(IPUtil.getIpAddr(contextRequest));
		orderRequest.setSpbillCreateIp(storageWxPayProperties.getSpbillCreateIp());
		//商品描述 例如: 腾讯充值中心-QQ会员充值
		orderRequest.setBody(body);
		//商户订单号 商户系统内部的订单号,32个字符内、可包含字母
		orderRequest.setOutTradeNo(tradeNo);
		//回调地址
		String wxPayPath = storageWxPayProperties.getNotifyUrl() + PayBusinessTypeConstant.DRIVER_PAY;
		orderRequest.setNotifyUrl(wxPayPath);
		//支付类型 APP MEWB .	
		orderRequest.setTradeType(tradeType);
//        orderRequest.setOpenid(openId); //app支付不需要openId
		orderRequest.setTotalFee(price.multiply(new BigDecimal(100)).intValue());
		return orderRequest;
	}

微信支付回调

	@PostMapping("/notify/{type}")
	@ResponseBody
	@ApiOperation(value = "微信支付回调", notes = "微信支付回调")
	public String notify(@PathVariable() String type, @RequestBody String xmlData) throws WxPayException {
		log.info("type:{}, xmlData:{}", type, xmlData);
		return wxPayService.notify(type, xmlData);
	}
		@Override
	public String notify(String type, String xmlData) throws WxPayException {
		WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
		notifyResult.checkResult(wxPayService, WxPayConstants.SignType.MD5, true);
		PayNotifyBusinessService businessService = PayBusinessFactory.getBusinessService(type);
		businessService.wxNofityHandler(xmlData, notifyResult);
		return WxPayNotifyResponse.success("成功");
	}

@Override
public void wxNofityHandler(String xmlData, WxPayOrderNotifyResult notifyResult) {
    // 获取商户交易订单号
    String outTradeNo = notifyResult.getOutTradeNo();
	//TODO 这里也可以做一些 appId machId 交易金额等一些校验
    TmOrderInfo orderInfo = tmOrderInfoService.getOrderInfoByJyNo(outTradeNo);
    if (orderInfo == null) {
        return;
    }
    if (StringUtils.equals(orderInfo.getOrderStatus(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
        return;
    }
    if (StringUtils.equals(WxPayConstants.ResultCode.SUCCESS, notifyResult.getReturnCode())) {
        // 支付成功逻辑处理
    }
}

查询订单

@Override
	public void wxPayQueryResultHandler(String jyNo) {
		TmOrderInfo orderInfo = tmOrderInfoService.getOrderInfoByJyNo(jyNo);
		if (orderInfo == null) {
			return;
		}
		try {
			WxPayOrderQueryResult wxPayOrderQueryResult = this.wxPayService.queryOrder("", jyNo);

			if (StringUtils.equals(orderInfo.getOrderStatus(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
				return;
			}

			if (StringUtils.equals(WxPayConstants.ResultCode.SUCCESS, wxPayOrderQueryResult.getReturnCode())) {
				if (!StringUtils.equals(wxPayOrderQueryResult.getTradeState(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
					// 查询结果不为成功时
					// throw new IllegalArgumentException(wxPayOrderQueryResult.getTradeStateDesc());
					return;
				}

				orderInfo.setOpenid(wxPayOrderQueryResult.getOpenid());
				// 微信订单号
				orderInfo.setTransactionId(wxPayOrderQueryResult.getTransactionId());
				orderInfo.setXmlData(wxPayOrderQueryResult.getXmlString());
				orderInfo.setTimeEnd(wxPayOrderQueryResult.getTimeEnd());
				orderInfo.setTradeType(wxPayOrderQueryResult.getTradeType());
				// 支付状态设置已支付
				orderInfo.setOrderStatus(WxPayConstants.WxpayTradeStatus.SUCCESS);
				orderInfo.setUpdateTime(new Date());
				orderInfo.setRealPayMoney(wxPayOrderQueryResult.getCashFee() == null ? "0" : String.valueOf(wxPayOrderQueryResult.getCashFee()));
				this.tmOrderInfoService.updateById(orderInfo);

				String businessId = orderInfo.getBusinessId();
				TmDriverTradeRecord driverTradeRecord = tmDriverTradeRecordService.getById(businessId);
				if (driverTradeRecord == null) {
					return;
				}
				driverTradeRecord.setIsSuccess(1);
				driverTradeRecord.setPayTime(DateUtil.parse(wxPayOrderQueryResult.getTimeEnd()));
				driverTradeRecord.setUpTime(new Date());
				this.tmDriverTradeRecordService.updateById(driverTradeRecord);
			}
		} catch (WxPayException e) {
			log.error("查询支付结果失败,", e);
			throw new IllegalArgumentException("查询支付结果失败,请稍后重试.");
		}
	}

支付宝支付

h5支付文档: https://opendocs.alipay.com/open/54/106682?pathHash=9ef0d2c7
异步通知文档:https://opendocs.alipay.com/open/204/105301
查询订单文档: https://opendocs.alipay.com/isv/02ti0w
app支付文档: https://opendocs.alipay.com/open/54/106370?pathHash=183e43fd

准备

alipay:
  app-id: 202101
  public-key: xx
  private-key: xx=
  gateway: https://openapi.alipay.com/gateway.do
  notify-url: http://xxx/storage/public/alipay/notify/
  char-set: UTF-8
# 支付成功返回地址
  return-url: http://xxx/app.html#/pages/payment/paymentDetail
# 取消支付返回地址
  quit-url: http://xxx/app.html#/pages/payment/paymentDetail

pom 添加依赖

<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.34.0.ALL</version>
</dependency>

配置类

@Configuration
public class AliPayConfig {

	@Bean
	public AlipayClient alipayClient(AlipayProperties alipayProperties) throws AlipayApiException {
		AlipayConfig alipayConfig = new AlipayConfig();
		//设置网关地址
		alipayConfig.setServerUrl(alipayProperties.getGateway());
		//设置应用ID
		alipayConfig.setAppId(alipayProperties.getAppId());
		//设置应用私钥
		alipayConfig.setPrivateKey(alipayProperties.getPrivateKey());
		//设置请求格式,固定值json
		alipayConfig.setFormat(AlipayConstants.FORMAT_JSON);
		//设置字符集
		alipayConfig.setCharset(AlipayConstants.CHARSET_UTF8);
		//设置支付宝公钥
		alipayConfig.setAlipayPublicKey(alipayProperties.getPublicKey());
		//设置签名类型
		alipayConfig.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
		//构造client
		return new DefaultAlipayClient(alipayConfig);
	}
}

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {
	/**
	 * 支付宝网关
	 */
	private String gateway;
	private String appId;
	private String publicKey;
	private String privateKey;
	private String charSet;
	private String format;
	private String signType;
	private String notifyUrl;
	private String returnUrl;
	private String quitUrl;
}

app下单

// 支付宝 app
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setOutTradeNo(tmDriverTradeRecord.getJyNo());
model.setBody("收银支付");
model.setSubject("收银支付");
model.setTimeoutExpress("30m");
model.setTotalAmount(tmDriverTradeRecord.getPayAmount().toString());
model.setProductCode("DRIVER_PAY_1");
request.setBizModel(model);
String notifyUrl = alipayProperties.getNotifyUrl() + PayBusinessTypeConstant.DRIVER_PAY;
request.setNotifyUrl(notifyUrl);
request.setBizModel(model);

//这里和普通的接口调用不同,使用的是sdkExecute
try {
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
    //就是orderString 可以直接给客户端请求,无需再做处理。
    if (response.isSuccess()) {
        log.info("支付宝返回body,{}", response.getBody());
        driverPayVo.setAliPayAppOrderResult(response.getBody());
        driverPayVo.setPayAppOrderResult(response.getBody());
    } else {
        throw new IllegalArgumentException(response.getMsg());
    }

} catch (AlipayApiException e) {
    log.error("支付宝支付失败.", e);
    throw new IllegalArgumentException("支付宝支付失败,原因:" + e.getMessage());
}

h5下单

AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(tmDriverTradeRecord.getJyNo());
model.setBody("收银支付");
model.setSubject("收银支付");
model.setTimeoutExpress("30m");
model.setTotalAmount(tmDriverTradeRecord.getPayAmount().toString());
model.setProductCode("DRIVER_PAY_1");
request.setBizModel(model);

String notifyUrl = alipayProperties.getNotifyUrl() + PayBusinessTypeConstant.DRIVER_PAY;
request.setNotifyUrl(notifyUrl);
// 支付成功返回地址
request.setReturnUrl(alipayProperties.getReturnUrl() + "?recNo=" + tmDriverTradeRecord.getRecNo());
// 用户取消后返回地址.
if (StringUtils.isNotBlank(alipayProperties.getQuitUrl())) {
    model.setQuitUrl(alipayProperties.getQuitUrl() + "?recNo=" + tmDriverTradeRecord.getRecNo());
}
request.setBizModel(model);
//这里和普通的接口调用不同,使用的是sdkExecute
try {
    AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
    //就是orderString 可以直接给客户端请求,无需再做处理。
    if (response.isSuccess()) {
        log.info("支付宝H5返回:{}", response.getBody());
        driverPayVo.setPayAppOrderResult(response.getBody());
    } else {
        log.error("e{}", response);
        throw new IllegalArgumentException("请求支付宝失败:" + response.getSubMsg());
    }
} catch (AlipayApiException e) {
    log.error("支付宝支付失败.", e);
    throw new IllegalArgumentException("支付宝支付失败,原因:" + e.getMessage());
}

回调

@PostMapping("/notify/{type}")
	@Operation(summary = "支付宝回调通知")
	public String notify(@PathVariable String type, @RequestParam Map<String, String> params) {
		log.info("type:{}, params:{}", type, params);
		return alipayService.notify(type, params);
	}


	@Override
	public String aliPayNofityHandler(Map<String, String> params) {
		String result = "failure";
		try {
			//异步通知验签
			boolean signVerified = AlipaySignature.rsaCheckV1(params,
					alipayProperties.getPublicKey(),
					AlipayConstants.CHARSET_UTF8,
					AlipayConstants.SIGN_TYPE_RSA2);
			if (!signVerified) {
				// TODO 验签失败则记录异常日志,并在response中返回failure.
				log.error("支付成功,异步通知验签失败!");
				return result;
			}
			log.info("支付成功,异步通知验签成功!");

			String outTradeNo = params.get("out_trade_no");
			TmOrderInfo orderInfo = tmOrderInfoService.getOrderInfoByJyNo(outTradeNo);
			if (orderInfo == null) {
				return "success";
			}
			if (StringUtils.equals(orderInfo.getOrderStatus(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
				return "success";
			}
			//2.判断 total_amount 是否确实为该订单的实际金额
			String totalAmount = params.get("total_amount");
			//3.校验通知中的 seller_id是否为 out_trade_no 这笔单据的对应的操作方
//			String sellerId = params.get("seller_id");
//			if (!sellerId.equals(config.getProperty("alipay.seller-id"))) {
//				log.error("商家PID校验失败");
//				return result;
//			}
			//4.验证 app_id 是否为该商家本身
			String appId = params.get("app_id");
			if (!appId.equals(alipayProperties.getAppId())){
				log.error("app_id校验失败");
				return result;
			}
			//在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,支付宝才会认定为买家付款成功
			String tradeStatus = params.get("trade_status");
			if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)){
				log.error("支付未成功");
				return result;
			}
			// 支付成功 处理逻辑.
			result = "success";
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return result;
	}

查询订单

@Override
	public void aliPayQueryResultHandler(String jyNo) {
		TmOrderInfo orderInfo = tmOrderInfoService.getOrderInfoByJyNo(jyNo);
		if (orderInfo == null) {
			return;
		}
		if (StringUtils.equals(orderInfo.getOrderStatus(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
			return;
		}

		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

		AlipayTradeQueryModel model = new AlipayTradeQueryModel();
		model.setOutTradeNo(jyNo);
		// 支付宝订单号
		// model.setTradeNo("");

		request.setBizModel(model);
		try {
			AlipayTradeQueryResponse response = alipayClient.execute(request);
			if (response.isSuccess()) {
				System.out.println(response.getBody());

				String tradeStatus = response.getTradeStatus();

				if (!"TRADE_SUCCESS".equals(tradeStatus) && !"TRADE_FINISHED".equals(tradeStatus)){
					log.error("查询结果, 支付未成功......" + tradeStatus);
					return;
				}
				// 支付成功 处理逻辑.

		} catch (AlipayApiException e) {
			log.error("查询支付宝接口失败.", e);
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值