Java服务端支付功能模块--(二)微信支付

上一篇写了关于支付宝支付的相关问题,本篇主要介绍微信支付的模块
微信支付可以大体分为5块:1.网页支付、2.App支付、3.H5外部浏览器支付、4.小程序支付、5.H5微信内部浏览器支付。这篇文章主要讲解 2、3、4、5这4种支付。
整体难度来说:H5微信内部浏览器支付>H5外部浏览器支付>小程序支付>App支付>网页支付。
编程语言为JAVA,采用的框架是SpringBoot+Mybatis.


控制层代码:
1.createPayOrder为三端统一调起的接口 只用appType和code区分出到底是调用哪个方法
2.因为H5外部浏览器支付需要获取用户的Ip地址所以主动去获取了请求的ip地址
3.isPayEarnest只是区分是否定金

@RestController
@RequestMapping("/wechatpay")
public class WeChatPayController {
   
    @Autowired
    private WeChatPayService weChatPayService;
    /**
     * 发起统一下单
     * @param appType 0为H5端 1为小程序 2为app
     * @param billNo Code是微信通过授权后获取的
     * @return Result
     */
    @RequestMapping(value = "/createPayOrder", method = RequestMethod.POST)
    public @ResponseBody Result createAppWeChatPayOrder(HttpServletRequest request, int appType, String billNo,
            String code, int isPayEarnest) {
        if (appType == 0) {
             if (code != null) {
                 return weChatPayService.h5CreateInnerPayOrder(billNo,code,isPayEarnest);
             }
            // h5
            return weChatPayService.h5CreatePayOrder(billNo, getIpAddr(request), isPayEarnest);
        } else if (appType == 1) {
            // 小程序
            return weChatPayService.wxAppCreatePayOrder(code, billNo, isPayEarnest);
        } else {
            // app
            return weChatPayService.appCreatePayOrder(appType, billNo, isPayEarnest);
        }
    }

    /**
     * 获取访问者IP
     * 
     * 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效。
     * 
     * 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-For获得第一个IP(用,分割),
     * 如果还不存在则调用Request .getRemoteAddr()。
     * 
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值,第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }

    /**
     * 查询订单
     * @param appType String
     * @param wxBillNo String
     * @param erpBillNo String
     * @return
     */
    @RequestMapping(value = "/orderquery")
    public @ResponseBody Result orderQuery(WeChatPayOrderQueryRequest request) {
        return weChatPayService.orderQuery(request);
    }
}

业务层代码:

```
@Service
public class WeChatPayServiceImpl implements WeChatPayService {
   
    private static Logger LOG = Logger.getLogger(WeChatPayServiceImpl.class);
    //微信支付配置参数
    @Autowired
    private WeChatPayProperties weChatPayProperties;
    private String orderDetail = "XXXX业务:";
    //支付业务
    @Autowired
    private PayService payService;

    @Override
    public Result wxAppCreatePayOrder(String code, String billNo, int isPayEarnest) {
        // 向微信请求获取openId
        Map<String, Object> openIdMap = getOpenId(initWxAppOpenIdParmMap(code));
        if (openIdMap == null) {
            return new Result(Constants.FAILURE_CODE, ErrorMsg.GET_WECHATPAY_OPENID);
        }
        String openId = (String) openIdMap.get("openid");
        if (openId == null) {
            return new Result(Constants.FAILURE_CODE, ErrorMsg.GET_WECHATPAY_OPENID);
        }
        // String session_key = (String) openIdMap.get("session_key");

        // 获取订单信息
        CarRentOrderPerson dto = payService.findOrder(billNo);
        //为了能多次吊起支付,调起支付订单号要加上时间戳
        String newbillNo = payService.createNewOrderNo(billNo);
        //保存吊起支付请求记录,方便维护(可有可无)
        payService.savePayRequest(newbillNo, dto, PayTypeEnums.WXAPP.getIndex(), SourceTypeEnums.WXAPP.getIndex());
        // 初始化微信小程序统一下单参数
        Map<String, String> params = initWxAppCreatePayBillParams(openId, orderDetail + dto.getModelname(), newbillNo,isPayEarnest == 1 ? dto.getPrepaydeposit().multiply((new BigDecimal(100))): dto.getReceivableamount().multiply((new BigDecimal(100))));
        // 向微信平台请求
        Result result = sendCreateOrderRequest(params);
        if (result.getCode() == Constants.FAILURE_CODE) {
            return result;
        }
        String prePayid = (String) result.getData();
        // 封装prePayId到返回参数中,直接返回给前端,前端直接拿着这个就可以调起支付
        return new Result(Constants.SUCCESS_CODE, "", initWxAppCreatePayBillReturnParams(prePayid));
    }

    @Override
    public Result appCreatePayOrder(int appType, String billNo, int isPayEarnest) {
        // 判断app类型 获取相应appId
        String appId = weChatPayProperties.getAppAppid();
        if (!(appType == 3 || appType == 2)) {
            return new Result(Constants.FAILURE_CODE, ErrorMsg.NO_SUCH_APP_TYPE);
        }
        // 获取预订单
        CarRentOrderPerson dto = payService.findOrder(billNo);
        if (dto == null) {
            return new Result(Constants.F
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值