整合支付宝支付与退款以及回调

本文档详细介绍了如何在Java Spring Boot项目中配置支付宝和微信支付,包括参数配置、支付服务初始化、退款操作以及异步通知处理。通过`BestPaySdk`进行支付接口调用,并在回调中验证签名、更新订单状态和处理退款流程。
摘要由CSDN通过智能技术生成
  1. 支付宝参数

    @Data
    @Component
    @ConfigurationProperties(prefix = "alipay")
    public class AliPayProperties {
    	
    	private String AppId;
    	//商户私钥
    	private String PrivateKey;
    	//支付宝公钥
    	private String AliPayPublicKey;
    	//异步通知地址
    	private String NotifyUrl;
    	//回调地址
    	private String ReturnUrl;
    	//网关
    	private String URL="https://openapi.alipay.com/gateway.do";
    	
    	/**
    	 * 密钥分为:公钥和密钥
    	 * 商户应用公钥签名:以在支付宝后台配置了:来源:生成密钥工具
    	 * 商户应用私钥签名:java应用需要==代码中需要配置:作用是商户支付签名:来源:生成密钥工具
    	 * 
    	 * 支付宝公钥签名:java应用需要==代码中需要配置:作用商户异步信息验证签名:支付宝后台配置商户的公钥之后会生成支付宝公钥
    	 * 支付宝私钥签名:(我们看不到)
    	 * RSA对称加密
    	 * 商户发起支付向支付宝服务器:商户发起支付(用商户应用私钥加密)--->支付宝服务器(商户应用公钥解密)
    	 * 支付宝向商户发送异步的通知:支付宝服务器(支付宝私钥加密)--->商户发起支付(支付宝公钥解密)
    	 * 
    	 * 商户(私钥)发送请求向支付宝服务器,支付宝服务器用 商户(公钥)解密商户发来的请求信息。
    	 * 支付宝服务器(私钥)异步通知,发送给商户(支付宝的公钥)解密支付宝发来的异步通知消息。
    	 */
    }

     

  2. 引入pom文件

            <!--best-pay-sdk -->
    		<dependency>
    			<groupId>cn.springboot</groupId>
    			<artifactId>best-pay-sdk</artifactId>
    			<version>1.3.1</version>
    		</dependency>

     

  3. 支付宝配置

    @Configuration
    public class BestPayConfig {
    	//微信和支付宝的参数
    	@Autowired
    	private WeachatProperties weachat;
    	@Autowired
    	private AliPayProperties alipay;
    
    	@Bean
    	public BestPayService BestPayconfig(WxPayConfig WxPayConfig) {
    		// 支付宝配置
    		AliPayConfig aliPayConfig = new AliPayConfig();
    		aliPayConfig.setAppId(alipay.getAppId());
    		aliPayConfig.setPrivateKey(alipay.getPrivateKey());
    		aliPayConfig.setAliPayPublicKey(alipay.getAliPayPublicKey());
    		aliPayConfig.setNotifyUrl(alipay.getNotifyUrl());// 支付宝异步通知信息
    		aliPayConfig.setReturnUrl(alipay.getReturnUrl());// 支付成功之后转跳到的页面
    		// 实现支付服务接口==根据不同的支付方式 返回对应的BestPayService对象
    		BestPayServiceImpl bestPay = new BestPayServiceImpl();
    		bestPay.setWxPayConfig(WxPayConfig);// 设置微信配置信息
    		bestPay.setAliPayConfig(aliPayConfig);// 设置支付宝的配置信息
    		return bestPay;
    	}
    	
    	//微信单独配置是为了controller层 支付完成之后 转跳页面 而支付宝内部直接设置就好
    	@Bean
    	public WxPayConfig WxPayConfig() {
    		// 微信配置
    		WxPayConfig WxConfig = new WxPayConfig();
    		WxConfig.setAppAppId(weachat.getOPAppId());//商户平台绑定的开放平台移动应用的openid
    		WxConfig.setAppId(weachat.getMPAppId());
    		WxConfig.setAppSecret(weachat.getMPSecret());
    		WxConfig.setMchId(weachat.getMchId());
    		WxConfig.setMchKey(weachat.getMchKey());
    		WxConfig.setKeyPath(weachat.getIDBook());
    		WxConfig.setNotifyUrl(weachat.getNotifyUrl());// 微信异步通知信息
    		WxConfig.setReturnUrl(weachat.getReturnUrl());// 微信支付成功的返回页面
    		return WxConfig;
    	}
    	
    }

     

  4. 支付宝支付

    // 微信和支付宝支付
    	public PayResponse createPay(String orderId,BestPayTypeEnum payType,String openid) {
    		//查询订单
    		OrderForm order=orders.selectByOrderId(orderId);
    		// 校验当前订单的支付状态(支付与未支付)
    		if (!StringUtils.equals(order.getStatus().toString(), OrderStatus.WAITINGPAY.getStatus().toString())) {
    			throw new PayException("订单支付状态不正确");
    		}
    		// 支付请求
    		PayRequest request = new PayRequest();
    		request.setOpenid(openid);
    		request.setOrderId(orderId);// 订单号
    		request.setOrderName(order.getOrderName());// 订单名字
    		request.setOrderAmount(order.getPrice().doubleValue());// 订单的总价
    		logger.info("订单的总价:" + order.getPrice().doubleValue());
    		// 支付方式:微信NATIVE支付、WXPAY_APP方式和支付宝APP、ALIPAY_PC、ALIPAY_WAP方式选择
    		request.setPayTypeEnum(payType);// 支付方式
    		return payService.pay(request);
    	}

     

  5. 支付宝退款

    public ServerResponse<String> alipayRefundRequest(String orderId) throws AlipayApiException {
    		AlipayClient alipayClient = new DefaultAlipayClient(payConfig.getURL(),
    				payConfig.getAppId(), payConfig.getPrivateKey(), "json", "UTF-8",
    				payConfig.getAliPayPublicKey(), "RSA2");
    		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
    		//根据订单号查询该订单
    		OrderForm orderForm=orders.selectByOrderId(orderId);
    		if(orderForm==null){
    			return ServerResponse.createByError(ResponseCode.ERROR,"退款订单号不存在");
    		}
    		AlipayRefund alipayRefund= new AlipayRefund();
    		alipayRefund.setOut_trade_no(orderForm.getOrderId());//这个是商户的订单号
    		alipayRefund.setTrade_no(orderForm.getOrderNum());//这个是支付宝的订单号
    		alipayRefund.setRefund_amount(orderForm.getPrice().toString());//退款金额
    		request.setBizContent(JSONObject.toJSONString(alipayRefund));//2个都可以,这个参数的顺序 不影响退款
    		AlipayTradeRefundResponse response = alipayClient.execute(request);
    		if (response.isSuccess()) {
    			orderForm.setRefuseTime(new Date());
    			orderForm.setStatus(OrderStatus.ORDERRFUSE.getStatus());
    			orders.updateById(orderForm);
    			//增加资金流水记录
    			CashFlow cash=new CashFlow();
    			cash.setId(Md5SaltUtils.getStringId());
    			cash.setOrderFormId(orderForm.getId());
    			cash.setType(OrderStatus.ORDEROUTCOME.getStatus());
    			cash.setCreateTime(new Date());
    			cashflow.insert(cash);
    			return ServerResponse.createBySuccess("退款成功");
    		} else {
    			return ServerResponse.createByError("退款失败",orderForm.getOrderId());
    		}
    	}

     

  6. 支付宝回调

    // 异步通知:支付异步通知验证是否支付成功
    	@Transactional
    	public String NotiyfiyInfor(String notiyBody) {
    		// 1.验证签名方式==防止在URL中修改参数信息-以验证微信返回的加密字符串是否正确 修改订单订单信息
    		PayResponse response = payService.asyncNotify(notiyBody);
    		// 2. 金额校验(从数据库查询用户支付订单的金额与实际微信回调信息中的订单金额做对比)
    		//查询订单
    		OrderForm order=orders.selectByOrderId(response.getOrderId());
    		if (order != null) {
    			logger.info(String.format("异步通知支付的订单号码:%s,异步通知支付的订单金额:%s", response.getOrderId(),response.getOrderAmount()));
    
    				// 数据库订单的金额与异步通知的订单金额是否相等
    				if (order.getPrice().compareTo(BigDecimal.valueOf(response.getOrderAmount())) != 0) {
    					throw new PayException("数据库订单金额与异步通知的订单金额不一致:" + response.getOrderAmount());
    				}
    				// 3. 判断订单是否支付成功==>修改订单的状态
    				order.setStatus(OrderStatus.PAYED.getStatus());
    				// 交易流水号
    				logger.info("交易流水号==>" + response.getOutTradeNo());
    				order.setOrderNum(response.getOutTradeNo());
    				order.setType(response.getPayPlatformEnum().getName());
    				order.setPayTime(new Date());
    				//更新订单数据订单信息
    				orders.updateById(order);
    				//增加资金流水记录
    				CashFlow cash=new CashFlow();
    				cash.setId(Md5SaltUtils.getStringId());
    				cash.setOrderFormId(order.getId());
    				cash.setType(OrderStatus.ORDERINCOME.getStatus());
    				cash.setCreateTime(new Date());
    				cashflow.insert(cash);
    			}
    		// 以上校验全部通过 判断支付的平台是微信还是支付宝,返回对应的格式的信息==>就要告诉微信或者支付宝不要再通知了,否则会有时间间隔的有回调信息发送给我们
    		if (response.getPayPlatformEnum() == BestPayPlatformEnum.WX) {
    			return "<xml>\n" + "<return_code><![CDATA[SUCCESS]]></return_code>\n"
    					+ "  <return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>";
    		} else if (response.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY) {
    			return "success";
    		}
    		throw new PayException("订单号不存在");
    	}

     

  7. application.properties参数引入

    alipay.AppId=xxx
    alipay.PrivateKey=xxx
    alipay.AliPayPublicKey=xxxx
    alipay.ReturnUrl=http://xxx/order/return
    alipay.NotifyUrl=http://xxx/order/notify

     

  8. 回掉和支付成功回掉页面

    // 接收的异步通知
    	@ResponseBody
    	@PostMapping("/notify")
    	public String PayNotify(@RequestBody String notiyBody) {
    		return payService.NotiyfiyInfor(notiyBody);
    	}
    
    	// 支付成功==返回支付成功的页面
    	@ResponseBody
    	@GetMapping("/return")
    	public String PaySuccessfully() {
    		return "支付成功";
    	}

     

  9. 发起支付

    @Transactional
    	@RequestMapping(value = "/alipay",method = RequestMethod.POST)
    	public ModelAndView AlipayPay(@RequestParam("orderId") String orderId,
    			@RequestParam("payType") BestPayTypeEnum paytype) {
    		Map<String, Object> map = new HashMap<String, Object>();
    		logger.info(String.format("支付宝开始支付:支付方式:%s,支付订单号码:%s", paytype, orderId));
    
    		PayResponse response = payService.createPay(orderId, paytype,"");
    		// 支付宝支付
    		if (paytype == BestPayTypeEnum.ALIPAY_PC) {
    			map.put("body", response.getBody());
    			return new ModelAndView("AlipayPC", map);
    		} else if (paytype == BestPayTypeEnum.ALIPAY_APP) {
    			map.put("body", response.getBody());
    			logger.info("ALIPAY_APP==>"+response.getBody());
    			return new ModelAndView("AlipayAPP", map);
    		} else if (paytype == BestPayTypeEnum.ALIPAY_WAP) {
    			map.put("body", response.getBody());
    			logger.info("ALIPAY_WAP==>"+response.getBody());
    			return new ModelAndView("AlipayWEB", map);
    		} 
    		throw new RuntimeException("支付状态不合法");
    	}

     

  10. 添加支付成功后的展示页面

    支付宝展示的页面

     

  11.  如果您没有密钥的话 可以联系我 我可以提供使用 私信联系我 点赞+关注+评论

     

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值