设计模式撸一遍,简单的开始。
起因
最近开始在做微信支付,都知道微信支付有几种方式,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地址:微信支付-简单点