当前位置: 首页 > news >正文

奉贤广州网站建设外贸手机网站建设

奉贤广州网站建设,外贸手机网站建设,织梦网站安装出现404 not found,商品展示型网站有哪些背景最近公司想把游戏包上到各个渠道上#xff0c;因此需要对接各种渠道#xff0c;渠道如下#xff0c;oppo、vivo、华为、小米、应用宝、taptap、荣耀、三星等应用渠道 主要就是对接登录、支付接口#xff08;后续不知道会不会有其他的#xff09;#x…背景最近公司想把游戏包上到各个渠道上因此需要对接各种渠道渠道如下oppo、vivo、华为、小米、应用宝、taptap、荣耀、三星等应用渠道                        主要就是对接登录、支付接口后续不知道会不会有其他的由于登录、支付前置都是一些通用的逻辑处理所以一开始我就想到了要用设计模式来做下面我画了一个图大家可以参考看一下        这里值得一提的是目前oppo比常规的渠道多了一个发货通知的接口我把几个接口都说说明下        登录用户通过oppo、vivo等进行登录并绑定我们内部账号中        支付回调用户使用oppo支付成功后要通知我们用户下单成功我们需要进行处理发货        发货通知我们发货成功后通知oppo发货成功了        前面两个接口其实很好理解主要是发货通知官方的文档如下看了也许你就明白了如下     如果 OPPO 服务端超过2 个小时仍未收到游戏服务端的发货结果请求则代表该笔订单发货失败将进入可退款状态用户可自助选择是否退款如果用户选择退款将进入OPPO 退款流程        对了没错用户可以退款我认为就是在对标苹果吧目前看小米和vivo都不需要有这个接口 流程图代码逻辑上面的就是设计图这里再简单的说下代码的结构逻辑是咋样的其实做过挺多次类似的处理了这两种模式的设计还是挺有意义的以下只是稍微说下大概的方式 AbstractChannelStrategy Slf4j public abstract class AbstractChannelStrategy{Resourceprotected ZXCUserParentDao userParentDao;Resourceprotected ZXCUsermpl userRepo;Resourceprivate ZXCOrderoDao orderInfoDao;Resourceprotected ApplicationContext applicationContext;Resourceprotected ZXCAppRepoImpl gameAppRepo;//获取用户注册类型public abstract UserTypeEnum getUserRegisterTypeEnum();//获取回调Url地址protected abstract String getCallBackUrlSuffix();//真正的支付成功处理public abstract void doNotifyOrderHandle(ChannelNotifyBaseBo notifyBaseBo, ChannelNotifyOrderResultBO notifyOrderResultBO, OrderInfo orderInfo) throws Exception;//游戏发货成功后的处理protected abstract DeliveryCallBackResultBo doDeliveryCallback(OrderInfo orderInfo, GameApp gameApp) throws Exception;//允许子类校验订单的其他信息protected void checkOrderOtherInfo(OrderInfo orderInfo){}public boolean notifyOrderHandle(ChannelNotifyBaseBo notifyBaseBo) {try {if(notifyBaseBo null) {return false;}//检查订单基础信息OrderInfo orderInfo commonOrderCheck(notifyBaseBo.getOrderNumber());checkOrderOtherInfo(orderInfo);ChannelNotifyOrderResultBO notifyOrderResultBO new ChannelNotifyOrderResultBO();doNotifyOrderHandle(notifyBaseBo, notifyOrderResultBO, orderInfo);boolean success notifyOrderResultBO.isSuccess();//成功后处理后续if(success) {log.info(notifyOrderHandle-订单号{}处理成功,进行后续处理, orderInfo.getOrderNumber());successOrder(orderInfo, notifyOrderResultBO.getTradeNo());}return success;} catch (Exception e) {log.error(doNotifyOrderHandle出现异常, e);throw new AppException(ErrorCode.SYS_OPERATOR_ERROR.code(), doNotifyOrderHandle调用时出现异常);}}public boolean deliveryCallback(String orderNumber) {OrderInfo orderInfo assertOrderInfo(orderNumber);GameApp gameApp gameAppRepo.getByAppNumber(orderInfo.getAppNumber());if(!Objects.equals(channelOrderRel.getRequestStatus(), 0)) {log.info(AbstractChannelAccountStrategy-deliveryCallback订单号为{}的请求状态不为未处理无须处理此时状态为{},来源为{}, orderNumber, channelOrderRel.getRequestStatus(), getLogSourceName());return true;}try {DeliveryCallBackResultBo deliveryCallBackResultBo doDeliveryCallback(orderInfo, gameApp);boolean success deliveryCallBackResultBo.isSuccess();//更新状态和次数channelOrderRel.setHttpContent(deliveryCallBackResultBo.getHttpContent());channelOrderRel.setRequestStatus(success ? 1 : null);int update channelOrderRelService.update(channelOrderRel);log.info(deliveryCallback-处理完成,更新的订单号为{},关联的channelOrderRel主键id为{},影响行数为{}, orderNumber, channelOrderRel.getId(), update);return success;} catch (Exception e) {log.error(AbstractChannelAccountStrategy-deliveryCallback订单号为{}的请求处理出现异常,来源为{}, orderNumber, getLogSourceName(), e);return false;}}protected OrderInfo commonOrderCheck(String orderNumber) {OrderInfo orderInfo assertOrderInfo(orderNumber);if(orderInfo.getPayWay() ! null !Objects.equals(getOrderPayWay().getCode(), orderInfo.getPayWay())) {throw new ZXCException(ZXCCode.OPERATOR_ERROR.code(), AbstractChannelAccountStrategy-订单号支付方式不对,此时订单号为 orderNumber);}return orderInfo;}private OrderInfo assertOrderInfo(String orderNumber) {OrderInfo orderInfo orderInfoDao.getByOrderNumber(orderNumber);if(orderInfo null) {throw new AppException(ErrorCode.NOT_FOUND_DATA.code(), AbstractChannelAccountStrategy-找不到关联的订单号数据,此时订单号为 orderNumber);}return orderInfo;}private void successOrder(OrderInfo orderInfo, String tradeNo) {boolean updated discountsService.updateOrderStatusAndDisCount(orderInfo, tradeNo);if(updated){// 发送事件applicationContext.publishEvent(new PaySuccessEvent(this, new PaySuccessEvent.PaySuccessEventData(orderInfo.getOrderNumber())));}}public String buildCallBackUrl() {//校验及简单处理一下数据String callBackUrlSuffix getCallBackUrlSuffix();if(StringUtil.isBlank(callBackUrlSuffix)) {throw new AppException(未配置回调地址);}if(!Objects.equals(/, callBackUrlSuffix.substring(0, 1))) {callBackUrlSuffix / callBackUrlSuffix;}String callBackUrlPrefix https://test.cn/v1/pay/callback;if(isLine()) {callBackUrlPrefix https://prod.cn/v1/pay/callback;}return callBackUrlPrefix callBackUrlSuffix;}虽然上面那个看起来很复杂,但是主要是子类方便,这里提供其中一个实现类OppoStrategyImpl Slf4j Component public class OppoStrategyImpl extends AbstractChannelAccountStrategy {Overridepublic UserTypeEnum getUserRegisterTypeEnum() {return UserTypeEnum.OPPO_USER;}Overrideprotected String getCallBackUrlSuffix() {return /oppo/callback;}Overridepublic void doNotifyOrderHandle(ChannelNotifyBaseBo notifyBaseBo, ChannelNotifyOrderResultBO notifyOrderResultBO, OrderInfo orderInfo) throws Exception {OppoOrderNotifyBo oppoOrderNotifyBo (OppoOrderNotifyBo) notifyBaseBo; //强制对象,几乎是不可能报错的,除非调用端出了问题//验证签名,这里是用oppo的公钥验签,因为私钥只有oppo有,所以别人无法伪造String baseString getBaseString(oppoOrderNotifyBo);boolean check OppoUtils.check(baseString, oppoOrderNotifyBo.getSign());if(!check) {log.info(OppoChannelAccountStrategyImpl-验签失败,此时订单号为{}, oppoOrderNotifyBo.getPartnerOrder());return;}//代表成功了,对数据进行填充notifyOrderResultBO.setSuccess(true);notifyOrderResultBO.setTradeNo(oppoOrderNotifyBo.getNotifyId()); //可能没有}// 生成 baseStringprivate static String getBaseString(OppoOrderNotifyBo ne) {StringBuilder sb new StringBuilder();sb.append(notifyId).append(ne.getNotifyId());sb.append(partnerOrder).append(ne.getPartnerOrder());sb.append(productName).append(ne.getProductName());sb.append(productDesc).append(ne.getProductDesc());sb.append(price).append(ne.getPrice());sb.append(count).append(ne.getCount());sb.append(attach).append(ne.getAttach());return sb.toString();}Overrideprotected OppoDeliveryResult doDeliveryCallback(OrderInfo orderInfo, GameApp gameApp) throws Exception {OppoDeliveryResult oppoDeliveryCallbackResult OppoUtils.postDeliveryOppo(orderInfo, gameApp);DeliveryCallBackResultBo deliveryCallBackResultBo new DeliveryCallBackResultBo();deliveryCallBackResultBo.setHttpContent(JsonUtils.Object2Json(oppoDeliveryCallbackResult));deliveryCallBackResultBo.setSuccess(oppoDeliveryCallbackResult.isSuccess());return deliveryCallBackResultBo;} }看起来是不是简单多了,当然第一个意义是不大,主要是后面的vivo、小米、华为等只需要提供对应的实现类即可        而且其他的可能都不需要doDeliveryCallback这个接口的实现因此其实还可以改进一下在底级类上面直接提供个成功的回调实现这里我就暂时不改了可能改为在底层提供个propertect方法然后直接调用也是可以的就当保存一下所有的交互数据得了而且可能有其他用途就是用来主动查询订单的结果       至于引用就更简单了通常都是有个类似于算门面的东西如下ChannelStrategyComponent Slf4j Component public class ChannelStrategyComponent {Resourceprivate ListAbstractChannelStrategy channelStrategyList;Resourceprivate ZXCUserParentDao userParentDao;Resourceprivate ZXCOrderDao orderInfoDao;public AbstractChannelStrategy getChannelAccountStrategy(UserTypeEnum userTypeEnum) {AbstractChannelStrategy channelAccountStrategy checkChannelAccountStrategy(userTypeEnum);if(channelAccountStrategy null) {throw new AppException(ErrorCode.SYS_ERROR.code(), 找不到关联的AbstractChannelAccountStrategy对象);}return channelAccountStrategy;}public AbstractChannelStrategy checkChannelAccountStrategyByOrderNumber(String orderNumber) {Order order orderDao.getByOrderNumber(orderNumber);//用支付方式直接去找for (AbstractChannelStrategy channelStrategy : channelStrategyList) {if(Objects.equals(orderInfo.getPayWay(), channelStrategy.getOrderPayWay().getCode())) {log.info(channelStrategy-从订单支付方式中找到处理器);return channelStrategy;}}//支付方式找不到再从用户注册类型去找节省一部数据库查询if(orderInfo ! null) {return checkChannelAccountStrategy(orderInfo.getUserName());}return null;} }怎么样看起来是不是很简单顺带一提上面的OppoUtils就是跟oppo对接的工具包这个就不提供了这部分肯定每个都不一样需要单独写         这篇文章主要是想说明一种封装思路而不是要说代码具体是怎么写的这个事 总结其实这个东西并不算很复杂可能跟我设计多次也有关系这种思路其实我是多少有点借助spring的设计你去看就会发现里面有很多类似这样的设计 后续补充补充一就像之前说的doDeliveryCallback方法并不是每个渠道都需要的所以并不需要弄为抽血方法可以提供默认实现子类根据需要实现即可以上是改动的代码改之前的结构protected abstract CallBackResultBo doDeliveryCallback() throws Exception每个子类都得强制实现改之后的结构protected CallBackResultBo doDeliveryCallback() throws Exception {return CallBackResultBo.buildDefaultSuccess(); }默认提供成功的实现这样一来子类就可以根据所需来选择是否需要覆盖了减少了不少代码补充二 之前的登录接口是设计为多个来给安卓调用的,比如以上两个接口oppo调用: https://zxc.com/oppo/loginvivo调用: https://zxc.com/vivo/login但是安卓说不好区分,他想统一调一个接口,如果是以外就麻烦了,但是在设计模式的加持下,现在实现的功能就非常简单了,只需要做几个事1.在抽象类 AbstractChannelStrategy添加 方法2.在子类提供实现3.在ChannelStrategyComponent提供获取方式最后在接收的通用参数定义 channelSource来源,然后子类跟它绑定起来就可以,代码如下抽象类添加//sdk端定义的渠道来源public abstract String getSdkChannelSource();子类实现Overridepublic String getSdkChannelSource() {return oppo;}上下文中添加获取即可,省略了这里
http://www.zqtcl.cn/news/65499/

相关文章:

  • 怎么查询网站是什么时候做的湖南网站设计外包费用
  • 上海 建网站网页美工设计教案网页元素设计
  • 济南一哥网站建设公司网站开发项目教程答案
  • 网站网页制作机构wordpress 小说插件
  • 成都网站建设公司湖南岚鸿建设银行网站为什么进不去
  • 做博客网站怎么赚钱吗建筑设计文字说明
  • 天津网站建设哪家做得好网站集约化建设的讲话
  • 南海网站制作公司扬州建设工程招聘信息网站
  • 赣州人才网赣州九一人才南昌seo数据监控
  • 西安建设局网站小孩把百度大搜是什么
  • 厦门专业的网站制作公司线上店免费推广的软件
  • 天津市工程建设项目报建网站网站建设具体步骤
  • 长宁专业网站制作公司什么是网站平台开发工具
  • 手机网站在线制作初级网站开发的自我推荐
  • 宁夏网站建设推广竞价托管多少钱
  • 做网站大家都找谁公司网站改版需要怎么做
  • 国际外贸网络交易平台黑帽seo论坛
  • 百度网站收录提交入口网站对于企业的好处
  • 18款免费软件app下载推荐长春seo推广外包
  • 网站导航栏图标贵阳网站制作 建设
  • wordpress搭建电影网站小程序api调用
  • 网站注册系统重庆网站建设技术托管
  • 北苑网站建设公司伍佰亿网站建设
  • 自己怎么做网址开网站石家庄网站建设价格低
  • 个人建站软件郑州网站建设找智巢
  • 深圳市建设交易网站WordPress 如何去域名授权
  • 做门户网站怎么赚钱运营推广网站建设
  • 做维修家具广告在哪个网站好柳州高端网站建设
  • 网站建设公司专业网站制作开发哪个网站做美食自媒体更好
  • 铜山区建设局局网站想给公司注册一个网站