设计模式撸一遍,简单的开始。

起因

最近开始在做微信支付,都知道微信支付有几种方式,jsapi调用,扫一扫支付还有H5支付等等,我在做jsapi的时候,各种配置搞的头疼,终于做好了,然后开始jsapi支付,想到还要搞这么多支付,杀了我吧,头疼,我就想能不能让支付简单点。

发现


细心一看,发现还是可以有路口解决的,(本章只对统一下单做了处理,后续,看我能力有没有长进了)调用的URL地址是一样的,参数有个重要的区别,trade_type 交易类型是通过参数区分的,也就是说。只要这个参数不同,就可以区别开各种支付。

准备

熟悉了一会,微信支付官网提供的支付SDK,对里面的调用有了解一会后,开始做准备。

1:准备支付时候的参数

2:准备统一下单的方法(所以的都必须满足)

其实想想就这么简单,我们只要准备以下参数。微信支付的SDK其他的都给我们做好了。我们做的是只是更加方便用而已。

构造模式-Builder来的PayHouse

利用构造模式,来填充参数。从上面就知道它们的支付区分只是参数不同。准备两个枚举类

1:区分统一下单的方法,jsapi&扫一扫

/**
 * 微信支付方式
 */
public enum WxPayTradeType {
    JSAPIPAY("JSAPI"),NATIVEPAY("NATIVE"),H5PAT("MWEB"), ;
    private String value;

    WxPayTradeType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
复制代码

2:区分AIP,统一下单等(为了后续做准备)

/**
 * 微信支付API
 */
public enum PayAPIType {
    UNIFIEDORDER("UNIFIEDORDER");
    private String value;

    PayAPIType(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}
复制代码

其他的参数就都用String了。参数还有几点要注意

1:在WXPayConfig里面。APPID,MchID,key已经存在了

2:参数中有许多固定值,比如:fee_type标记货币(默认人民币)终端IPspbill_create_ip,其实都是看需求

最后,形成的是

PayHouse payHouse = new PayHouse.Builder(new MyConfig())
        .setAttach("")
        .setOpenid("")
        .setBody("")
        .setOutTradeNo("")
        .setTotalFee("")
        .setTradeType(WxPayTradeType.JSAPIPAY)
        .setPayAPIType(PayAPIType.UNIFIEDORDER)
        .setProductId("")
        .build();复制代码

这个负责参数。那么执行呢?

统一性下单的unifiedorder

微信支付有很多的API,但我觉得给它们一个一个单独开出来,单一原则。虽然不知道这个对不对,但是方便最重要。为了以后兼容支付宝的,还是要接口开发

public interface Unifiedorder {

    /**
     * 微信统一下单
     * @param payHouse
     * @return
     */
     public Map<String,String> PayUnifiedorder(PayHouse payHouse);

}复制代码

实现其类,代码如下:

public class WxUnifiedorder implements Unifiedorder {

    public Log logger = LogFactory.getLog(getClass());

    @Override
    public Map<String, String> PayUnifiedorder(PayHouse payHouse) {
        WXPay wxpay = new WXPay(payHouse.getMyConfig());
        Map<String, String> data = new HashMap<String, String>();
        if (payHouse.getDeviceInfo() != null)data.put("device_info", payHouse.getDeviceInfo());
        if (payHouse.getNonceStr() != null)data.put("nonce_str", payHouse.getNonceStr());
        if (payHouse.getBody() != null)data.put("body", payHouse.getBody());
        if (payHouse.getDetail() != null)data.put("detail", payHouse.getDetail());
        if (payHouse.getAttach() != null)data.put("attach", payHouse.getAttach());
        if (payHouse.getOutTradeNo() != null)data.put("out_trade_no", payHouse.getOutTradeNo());
        if (payHouse.getFeeType() != null)data.put("fee_type", payHouse.getFeeType());
        if (payHouse.getTotalFee() != null)data.put("total_fee", payHouse.getTotalFee());
        if (payHouse.getSpbillCreateIp() != null)data.put("spbill_create_ip", payHouse.getSpbillCreateIp());
        if (payHouse.getTimeStart() != null)data.put("time_start", payHouse.getTimeStart());
        if (payHouse.getTimeExpire() != null)data.put("time_expire", payHouse.getTimeExpire());
        if (payHouse.getGoodsTag() != null)data.put("goods_tag", payHouse.getGoodsTag());
        if (payHouse.getNotifyUrl() != null)data.put("notify_url", payHouse.getNotifyUrl());
        if (payHouse.getTradeType() != null)data.put("trade_type", payHouse.getTradeType().getValue());
        if (payHouse.getProductId() != null)data.put("product_id", payHouse.getProductId());
        if (payHouse.getLimitPay() != null)data.put("limit_pay", payHouse.getLimitPay());
        if (payHouse.getOpenid() != null)data.put("openid", payHouse.getOpenid());
        if (payHouse.getReceipt() != null)data.put("receipt", payHouse.getReceipt());
        if (payHouse.getSceneInfo() != null)data.put("scene_info", payHouse.getSceneInfo());
        try {
            Map<String, String> resp = null ;
            if (payHouse.getTradeType() == WxPayTradeType.NATIVEPAY){//扫一扫
                resp = wxpay.unifiedOrder(data);
                logger.info(resp);
                return resp ;
            }else if (payHouse.getTradeType() == WxPayTradeType.JSAPIPAY){//JSAPI
                resp = wxpay.unifiedOrder(data);
                Map<String, String> jsapipayMap = new HashMap<String, String>();
                jsapipayMap.put("appId",payHouse.getMyConfig().getAppID());
                jsapipayMap.put("timeStamp", System.currentTimeMillis()+"");
                jsapipayMap.put("nonceStr",WXPayUtil.generateNonceStr());
                jsapipayMap.put("package","prepay_id="+resp.get("prepay_id"));
                jsapipayMap.put("signType","MD5");
                jsapipayMap.put("paySign",WXPayUtil.generateSignature(jsapipayMap,payHouse.getMyConfig().getKey()));
                jsapipayMap.put("return_code",resp.get("return_code"));
                logger.info(jsapipayMap);
                return jsapipayMap ;
            }else if (payHouse.getTradeType() == WxPayTradeType.H5PAT){//还没有申请

            }
            logger.info("is null");
            return resp;
        } catch (Exception e) {
            logger.info(e);
            e.printStackTrace();
            return null;
        }
    }

}复制代码

执行

希望能一个方法就可以调用所有的,返回。所有在PayHouse里面放入执行方法(后续会有改动,希望可以通过观察者获得最终接口)

public Map<String,String> implement(){
    Map<String,String> map = null ;
    if (payAPIType == PayAPIType.UNIFIEDORDER){//区分API
        map = new WxUnifiedorder().PayUnifiedorder(this);
    }
    return map;
}复制代码

看看效果

下面展示出不同支付方式的代码

1:JSAPI调用

String total_fee = orderGoodsDTO.getGoodsFinalPirce()*100+"";
//合成表单
PayHouse payHouse = new PayHouse.Builder(new MyConfig())
        .setAttach("")
        .setOpenid("")
        .setBody("")
        .setOutTradeNo("")
        .setTotalFee("")
        .setTradeType(WxPayTradeType.JSAPIPAY)
        .setPayAPIType(PayAPIType.UNIFIEDORDER)
        .setProductId("")
        .build();
Map<String, String> implement = payHouse.implement();
return implement ;复制代码

2:扫一扫

String total_fee = orderGoodsDTO.getGoodsFinalPirce()*100+"";
//合成表单
PayHouse payHouse = new PayHouse.Builder(new MyConfig())
        .setAttach("")
        .setBody("")
        .setOutTradeNo("")
        .setTotalFee("")
        .setTradeType(WxPayTradeType.NATIVEPAY)
        .setPayAPIType(PayAPIType.UNIFIEDORDER)
        .setProductId("")
        .build();
Map<String, String> implement = payHouse.implement();复制代码

返回的Map直接转成JSON给前端就可以使用,亲测。(总于有篇没有看其他同志的博客写的了)

谢谢大家观看,后续会补。觉得支付是个大工程,是可以完善我对设计模式的学习

GitHub地址:微信支付-简单点