5支付(freemarker)

编程入门 行业动态 更新时间:2024-10-28 18:26:09

5支付(<a href=https://www.elefans.com/category/jswz/34/1761218.html style=freemarker)"/>

5支付(freemarker)

文章目录

  • 1概念
  • 2微信支付文档
    • 2.1 简单测试一下统一下单的接口
  • 3支付demo(封装好,直接用):
  • 4简单的使用
    • 4.1引入依赖
    • 4.2编写
    • 4.3 前端生成二维码
      • 4.3.1 引入freemarker
      • 4.3.2编写controller
      • 4.3.3 编写页面
      • 4.3.4测试
      • 4.3.5修改controller,获取二维码给页面
      • 4.3.6提取配置代码
      • 4.3.7异步通知
      • 4.3.8支付宝
  • 5 最终代码
    • 5.1 controller
    • 5.2 service
    • 5.3BestPayConfig
    • 5.4配置文件
  • 6过程说明

1概念


支付结果以异步为准

2微信支付文档

.php?chapter=6_4

2.1 简单测试一下统一下单的接口

.php?chapter=9_1

主要看签名算法
.php?chapter=4_3

3支付demo(封装好,直接用):

下边的demo的分解学习;

4简单的使用

4.1引入依赖

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

4.2编写


每次调用返回的二维码文本是不一样的。


4.3 前端生成二维码

用这个js就可以做到

4.3.1 引入freemarker

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

4.3.2编写controller

4.3.3 编写页面

4.3.4测试




注意:

只要订单号不变,不会重复支付的



4.3.5修改controller,获取二维码给页面

4.3.6提取配置代码

因为异步通知也需要校验签名,创建支付也需要,提取出来:

修改代码:

添加啦@bean ,项目启动啦就执行啦代码

4.3.7异步通知

4.3.8支付宝

5 最终代码

5.1 controller

package com.imooc.pay.controller;import com.imooc.pay.pojo.PayInfo;
import com.imooc.pay.service.impl.PayService;
import com.lly835.bestpay.config.WxPayConfig;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.model.PayResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;/*** Created by 廖师兄*/
@Controller
@RequestMapping("/pay")
@Slf4j
public class PayController {@Autowiredprivate PayService payService;@Autowiredprivate WxPayConfig wxPayConfig;@GetMapping("/create")public ModelAndView create(@RequestParam("orderId") String orderId,@RequestParam("amount") BigDecimal amount,@RequestParam("payType") BestPayTypeEnum bestPayTypeEnum) {PayResponse response = payService.create(orderId, amount, bestPayTypeEnum);//支付方式不同,渲染就不同, WXPAY_NATIVE使用codeUrl,  ALIPAY_PC使用bodyMap<String, String> map = new HashMap<>();if (bestPayTypeEnum == BestPayTypeEnum.WXPAY_NATIVE) {map.put("codeUrl", response.getCodeUrl());map.put("orderId", orderId);map.put("returnUrl", wxPayConfig.getReturnUrl());return new ModelAndView("createForWxNative", map);}else if (bestPayTypeEnum == BestPayTypeEnum.ALIPAY_PC) {map.put("body", response.getBody());return new ModelAndView("createForAlipayPc", map);}throw new RuntimeException("暂不支持的支付类型");}@PostMapping("/notify")@ResponseBodypublic String asyncNotify(@RequestBody String notifyData) {return payService.asyncNotify(notifyData);}@GetMapping("/queryByOrderId")@ResponseBodypublic PayInfo queryByOrderId(@RequestParam String orderId) {log.info("查询支付记录...");return payService.queryByOrderId(orderId);}
}

5.2 service

package com.imooc.pay.service.impl;import com.imooc.pay.dao.PayInfoMapper;
import com.imooc.pay.enums.PayPlatformEnum;
import com.imooc.pay.pojo.PayInfo;
import com.imooc.pay.service.IPayService;
import com.lly835.bestpay.enums.BestPayPlatformEnum;
import com.lly835.bestpay.enums.BestPayTypeEnum;
import com.lly835.bestpay.enums.OrderStatusEnum;
import com.lly835.bestpay.model.PayRequest;
import com.lly835.bestpay.model.PayResponse;
import com.lly835.bestpay.service.BestPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.math.BigDecimal;/*** Created by 廖师兄*/
@Slf4j
@Service
public class PayService implements IPayService {@Autowiredprivate BestPayService bestPayService;@Autowiredprivate PayInfoMapper payInfoMapper;/*** 创建/发起支付** @param orderId* @param amount*/@Overridepublic PayResponse create(String orderId, BigDecimal amount, BestPayTypeEnum bestPayTypeEnum) {//写入数据库PayInfo payInfo = new PayInfo(Long.parseLong(orderId),PayPlatformEnum.getByBestPayTypeEnum(bestPayTypeEnum).getCode(),OrderStatusEnum.NOTPAY.name(),amount);payInfoMapper.insertSelective(payInfo);PayRequest request = new PayRequest();request.setOrderName("4559066-最好的支付sdk");request.setOrderId(orderId);request.setOrderAmount(amount.doubleValue());request.setPayTypeEnum(bestPayTypeEnum);PayResponse response = bestPayService.pay(request);log.info("发起支付 response={}", response);return response;}/*** 异步通知处理** @param notifyData*/@Overridepublic String asyncNotify(String notifyData) {//1. 签名检验PayResponse payResponse = bestPayService.asyncNotify(notifyData);log.info("异步通知 response={}", payResponse);//2. 金额校验(从数据库查订单)//比较严重(正常情况下是不会发生的)发出告警:钉钉、短信PayInfo payInfo = payInfoMapper.selectByOrderNo(Long.parseLong(payResponse.getOrderId()));if (payInfo == null) {//告警throw new RuntimeException("通过orderNo查询到的结果是null");}//如果订单支付状态不是"已支付"if (!payInfo.getPlatformStatus().equals(OrderStatusEnum.SUCCESS.name())) {//Double类型比较大小,精度。1.00  1.0if (payInfo.getPayAmount()pareTo(BigDecimal.valueOf(payResponse.getOrderAmount())) != 0) {//告警throw new RuntimeException("异步通知中的金额和数据库里的不一致,orderNo=" + payResponse.getOrderId());}//3. 修改订单支付状态payInfo.setPlatformStatus(OrderStatusEnum.SUCCESS.name());payInfo.setPlatformNumber(payResponse.getOutTradeNo());payInfoMapper.updateByPrimaryKeySelective(payInfo);}//TODO pay发送MQ消息,mall接受MQ消息if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.WX) {//4. 告诉微信不要再通知了return "<xml>\n" +"  <return_code><![CDATA[SUCCESS]]></return_code>\n" +"  <return_msg><![CDATA[OK]]></return_msg>\n" +"</xml>";}else if (payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY) {return "success";}throw new RuntimeException("异步通知中错误的支付平台");}@Overridepublic PayInfo queryByOrderId(String orderId) {return payInfoMapper.selectByOrderNo(Long.parseLong(orderId));}
}

5.3BestPayConfig

package com.imooc.pay.config;import com.lly835.bestpay.config.AliPayConfig;
import com.lly835.bestpay.config.WxPayConfig;
import com.lly835.bestpay.service.BestPayService;
import com.lly835.bestpay.service.impl.BestPayServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** Created by 廖师兄*/
@Component
public class BestPayConfig {@Autowiredprivate WxAccountConfig wxAccountConfig;@Autowiredprivate AlipayAccountConfig alipayAccountConfig;@Beanpublic BestPayService bestPayService(WxPayConfig wxPayConfig) {AliPayConfig aliPayConfig = new AliPayConfig();aliPayConfig.setAppId(alipayAccountConfig.getAppId());aliPayConfig.setPrivateKey(alipayAccountConfig.getPrivateKey());aliPayConfig.setAliPayPublicKey(alipayAccountConfig.getPublicKey());aliPayConfig.setNotifyUrl(alipayAccountConfig.getNotifyUrl());aliPayConfig.setReturnUrl(alipayAccountConfig.getReturnUrl());BestPayServiceImpl bestPayService = new BestPayServiceImpl();bestPayService.setWxPayConfig(wxPayConfig);bestPayService.setAliPayConfig(aliPayConfig);return bestPayService;}@Beanpublic WxPayConfig wxPayConfig() {WxPayConfig wxPayConfig = new WxPayConfig();wxPayConfig.setAppId(wxAccountConfig.getAppId());wxPayConfig.setMchId(wxAccountConfig.getMchId());wxPayConfig.setMchKey(wxAccountConfig.getMchKey());//192.168.50.101 同一局域网可访问//125.121.56.227 云服务器可行,家庭宽带不行(路由器、光猫)wxPayConfig.setNotifyUrl(wxAccountConfig.getNotifyUrl());wxPayConfig.setReturnUrl(wxAccountConfig.getReturnUrl());return wxPayConfig;}
}

5.4配置文件

  
wechat:mpAppId: wxd898xxxxmchId: 1483xxxxmchKey: C5245D70xxxxxkeyPath: /var/weixin_cert/wxpay.p12notifyUrl: : wxxxxxxxxxxx6bf9bminiAppSecret: xxbc6xxxxxxxxxxxxxx9c49dappAppId: wxxxxxxxxxxxx43b0alipay:appId: appIdprivateKey: 商户私钥aliPayPublicKey: 支付宝公钥notifyUrl: : : true #是否使用沙箱

6过程说明

申请微信商家账号和开通支付功能,我们主要是为了拿到两个属性:一个是微信支付商户号,另一个是微信支付API秘钥。

a用户去我们的网站选择了一个商品点击购买,然后访问我们后台的接口,这个接口需要处理的逻辑是首先在我们系统里生成一条订单,然后调用微信的统一下单接口,微信的统一下单接口需要根据文档上指定的一些参数进行生成签名和加密传输,微信后台系统会给我们返回一个code_url链接,我们后台的代码拿到这个code_url链接后将它转成二维码图片,返给前端展示,然后用户使用微信扫一扫进行支付;

在配置类已经指定啦支付回调的接口地址

b、用户支付后,微信会回调我们的接口,告诉我们支付的结果,所以我们需要再写一个微信支付回调的接口
这个接口的大概逻辑应该是:拿到支付成功的状态去更新我们系统里订单表里的状态为已支付,然后给微信返回我们已经收到通知的信息;如果我们的接口没给微信返回已经收到通知的信息,微信那边会有一定的策略,它会每隔一段时间去调一次我们的接口试一下,直到成功或者直到达到一定的次数或者达到一定的时间,才会停止调用
还有就是我们这边超过一定的时间没收到微信的回调的话,我们也可以主动调微信的接口去查询相应的支付状态

更多推荐

5支付(freemarker)

本文发布于:2024-02-12 17:54:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1688800.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:freemarker

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!