腾讯云市场接入 saas Java代码 自动生产接入指南

1.话不多说们直接上图:

看来看去网上都没有腾讯云市场接入java的编写可以借鉴,还是自己发一个开荒。

在这里插入图片描述

1. 就是一个问题 怎么接入自己得saas产品实现自己或你公司的产品售卖 ,这里以腾讯云为例,华为云 阿里云较为简单。需要小伙伴留言。

2. 查阅:–》官方接入说明地址,建议把文档看一下。再看代码

3. 调试地址:腾讯云调试地址,填写下图的参数和地址啥的,切记地址需要https的,调试接口可使用【natapp工具】 内网穿透可以用用。其他也行方便调试。

在这里插入图片描述

2.基于以上的了解 ,开发都懂 直接上代码(给出逻辑,开发的人应该能跟着快速实现):

2.0 实体类

@Data
public class AppTxOrderDTO extends AppTxOrder {

    private static final long serialVersionUID=1L;
    // 地址参数
    private String signature;
    private String token;
    private String timestamp;
    private String eventId; // 很重要的参数 根据它去看是什么操作
    private String action;
    private String requestId;
    private String echoback;
     // body 参数(承接创建实例 续费实例 )
    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.ID_WORKER)
    private Long id;

    @ApiModelProperty(value = "订单 ID")
    private String orderId;

    @ApiModelProperty(value = "购买者账号 ID")
    private String accountId;

    @ApiModelProperty(value = "用户在腾讯云开放平台的标识")
    private String openId;

    @ApiModelProperty(value = "云市场产品 ID")
    private Integer productId;

    @ApiModelProperty(value = "云市场的实例ID")
    private String resourceId;

    @ApiModelProperty(value = "接口请求标识,主要应用于问题排查")
    private String requestId;

    @ApiModelProperty(value = "实例标识 ID")
    private String signId;

    @ApiModelProperty(value = "新的实例到期时间(yyyy-MM-dd HH:mm:ss)")
    private Date instanceExpireTime;


    @ApiModelProperty(value = "租户id")
    private String tId;

    @ApiModelProperty(value = "产品信息")
    private Object productInfo;

    @ApiModelProperty(value = "类型")
    private String type;

    @TableField(exist = false)
    @ApiModelProperty(value = "订单扩展信息")
    private AppTxExtendinfo extendInfo;

    @TableField(exist = false)
    @ApiModelProperty(value = "订单扩展信息")
    private AppTxUsercollectioninfo userCollectionInfo;
}

public class AppTxProduct implements Serializable {
 @ApiModelProperty(value = "唯一实例id")
    private String signId;

    @ApiModelProperty(value = "购买的产品名称")
    private String productName;

    @ApiModelProperty(value = "是否为试用,1:是,false:0")
    private boolean isTrial;

    @ApiModelProperty(value = "产品规格,是试用时为空")
    private String spec;

    @ApiModelProperty(value = "购买时长,是试用时为空")
    private Integer timeSpan;

    @ApiModelProperty(value = "购买时长单位(y、m、d、h、t 分别代表年、月、日、时、次),是试用时为空	注:这里所描述的年、月为自然年、自然月的概念;举例:2月1日买的包月商品,3月1日到期")
    private String timeUnit;

    @ApiModelProperty(value = "计量数量,仅当是计量类商品才存在")
    private String flowSpan;

    @ApiModelProperty(value = "计量单位,仅当是计量类商品才存在")
    private String flowUnit;

    @ApiModelProperty(value = "批量购买的规格数量,默认为1")
    private Integer cycleNum;
}

2.1 工具类

package xxxxx.utils;



import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.swing.*;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @Date 2021/11/12 17:50
 * @Created by 
 *  腾讯工具类 :主要是进行验签
 */
public class TxUtils {


    //让工具类不实例化
    private TxUtils(){};
    /**
     *  腾讯云市场 - 验证签名
     * @return
     */

   static  Map<String,String> map = new HashMap<>();

    public static boolean  signature(Map<String,String> map){
        // 判断timestamp 是否超时
        long l = System.currentTimeMillis() / 1000;
        long l1 = l - new Long(map.get("timestamp"));
        if (l1>30){
            return false;
        }
        // 1.字典排序
        List<String> list = new ArrayList<>();
        list.add(map.get("timestamp"));
        list.add(map.get("eventId"));
        list.add("f1ce146677a34cac8d6754c0a2f014ff");//写死的token值,和腾讯云要一样
        Collections.sort(list,(o1,o2)->{
            try {
                String s1 = new String(o1.getBytes("GB2312"), "ISO-8859-1");
                String s2 = new String(o2.getBytes("GB2312"), "ISO-8859-1");
                return s1.compareTo(s2);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
           return 0;
        });
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : list) {
            stringBuilder.append(s);
        }
        String item = stringBuilder.toString();
        // 2.加密+验签
        MessageDigest  messageDigest = null;
        try {
            // jdk 自带
            messageDigest = MessageDigest.getInstance("SHA-256"); // 可选MD5、SHA1、SHA-256、SHA-512
            // update方法负责加密
            messageDigest.update(item.getBytes());
            //摘要结果,加密后的数组
            byte[] digest = messageDigest.digest();
            StringBuilder res = new StringBuilder();
            for (byte b : digest) {
                // 对每个字节转为16进制输出结果
                res.append(String.format("%02X", b).toLowerCase());
            }
            //参数验签
           return  map.get("signature").equals(res.toString());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     *  腾讯云市场 - 参数获取
     */
    public static Map getRequestParams(HttpServletRequest request){
        // 定义结果集
        Map<String,String> map = new HashMap<>();
        //解析出url内容
        Map<String, String[]> paramsMap = request.getParameterMap();
        // 获取URI的参数
        for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) {
            map.put(entry.getKey(),entry.getValue()[0]);
        }
        return map;
    }

    /**
     *  腾讯云市场 - 时长单位计算
     *  y、m、d、h、t 分别代表年、月、日、时、次),是试用时为空
     * 注:这里所描述的年、月为自然年、自然月的概念;举例:2月1日买的包月商品,3月1日到期
     */
    public static Date expireTime(Date date ,Integer time, String unit) {
        // 不使用t
        // 计算指定时间段从此刻往后的偏移量的时间
        switch (unit) {
            case "y":
                return DateUtil.offset(date, DateField.YEAR, time);
            case "m":
                return DateUtil.offset(date, DateField.MONTH, time);
            case "d":
                return DateUtil.offset(date, DateField.DAY_OF_MONTH, time);
            default:
                return DateUtil.offset(date, DateField.HOUR_OF_DAY, time);
        }
    }

}
  
   

2.2 接口控制层

@RestController
@Api(value = "腾讯服务商市场", tags = "腾讯服务商市场")
@RequestMapping
@Slf4j
public class TxMarketController {

    @Autowired
    RenterClient renterClient;

    @PostMapping (value = "/tencentMarket",produces = "application/json;charset=UTF-8")
    @ApiOperation("腾讯云市场请求-创建实例")
    public String createInstance(HttpServletRequest request ,@RequestBody AppTxOrderDTO appTxOrderDTO) throws Exception {
        Map requestParams = TxUtils.getRequestParams(request);
        boolean signature = TxUtils.signature(requestParams);
        if(appTxOrderDTO.getEchoback()!=null){
            Map<String,Object> map = new HashMap();
            map.put("echoback",appTxOrderDTO.getEchoback());
            return JSON.toJSONString(map);
        }
        if (!signature){
          return "参数验签错误";
        }
        AppTxOrder appTxOrder = new AppTxOrder();
        BeanUtils.copyProperties(appTxOrderDTO,appTxOrder);
        String res = TxDispatcherServlet.dispatch(appTxOrderDTO.getAction(), appTxOrder);
        return res;
    }
}

2.3 转发到具体逻辑类:

@Component
public class TxDispatcherServlet implements ApplicationContextAware {
    private static ApplicationContext context;
   // 这里代码利用了反射 和mvc模式有点像 不要看不懂了
   public static  String dispatch (String action,AppTxOrder appTxOrder) throws Exception {
       AppTxOrderService bean = context.getBean(AppTxOrderService.class);
       String result  = (String)bean.getClass().getMethod(action, new Class[]{AppTxOrder.class}).invoke(bean, appTxOrder);
       return result;
   }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}

2.4 实现层接口(实现它即可,具体代码涉及公司不易展示,根据自己的产品实现一下几个方法的具体逻辑就可以,具体包括(创建实例 续费实例 过期实例 销毁实例。四个实例对应腾讯云接口的调试))

public interface TencentService extends IService<AppTxOrder> {
    //续费实例
    String createInstance(AppTxOrder appTxOrder);
    //续费实例
    String renewInstance(AppTxOrder appTxOrder);
    //过期实例
    String expireInstance(AppTxOrder appTxOrder);
    //销毁实例
    String destroyInstance(AppTxOrder appTxOrder);
}

创建如下类:
举例:
@Service  // 实现以上四个接口
public class TencentServiceImpl extends ServiceImpl<AppTxOrderMapper, AppTxOrder> implements TencentService{
  
  //续费实例
    String createInstance(AppTxOrder appTxOrder){
     // 步骤:两步
     
    // 1.了解官方要求的返回结构,构建返回结构体(不是这个结构直接报错不通过,不要踩坑)
    /**
     官方举例返回体,根据改:
     -------------------返回JSON样式-----------------------------
     {
	"signId": "36441d902ba",
	"appInfo": {
		"website": "http://www.example.com",
		"authUrl": "http://www.example.com/oauth/login"
	},
	"additionalInfo": [{
		"name": "注意",
		"value": "这是一条注意"
	}, {
		"name": "说明",
		"value": "这是说明"
	}]
	}
------------------------------------------------
    **/
     // 1.1 模仿构建
     Map<String,Object>  map = new HashMap();
        Map<String,String> mapInfo = new HashMap();
        mapInfo.put("");//1.填公司\产品网址
        List<Map<String,String>> additionalInfo = new ArrayList<>();
         // 0.构建并返回有权限的用户账号
        map.put("signId", "");// 2.填实例
        // 账号
        Map<String,String> userNameMap = new HashMap();
        userNameMap.put("name","账号");
        userNameMap.put("value","");// 3.填用户名
        additionalInfo.add(userNameMap);
        // 密码
        Map<String,String> passNameMap = new HashMap();
        passNameMap.put("name","密码");
        passNameMap.put("value","");// 4.填密码
        additionalInfo.add(passNameMap);
        // 说明
        Map<String,String> noteMap = new HashMap();
        noteMap.put("name","备注");
        noteMap.put("value","尊敬的用户:已为您开通对应的初始账号/密码与相关权限,请使用用初始账号/密码登录网站!"); // 可以更换成自己的
        additionalInfo.add(noteMap);
        map.put("appInfo",mapInfo);
        map.put("additionalInfo",additionalInfo);
 //
  //
   //
    //
//         2.具体逻辑:主要是开通资源返回(这部分自己的售卖或者开通逻辑)
 //
  //
   //
    //
        return  JSON.toJSONString(map);
    
  	 }
    //续费实例
    String renewInstance(AppTxOrder appTxOrder){
    //两步
       // 1.具体逻辑:主要是续费资源
     //2. 返回:这个返回很简单
       Map<String,Object> map = new HashMap();
        map.put("success","true");
      return JSON.toJSONString(map);
		}
    //过期实例
    String expireInstance(AppTxOrder appTxOrder){
     //两步
       // 1.具体逻辑:主要是处理资源
     //2. 返回:这个返回很简单
       Map<String,Object> map = new HashMap();
        map.put("success","true");
		return JSON.toJSONString(map);
		}
        
    //销毁实例
    String destroyInstance(AppTxOrder appTxOrder){
     //两步
       // 1.具体逻辑:主要是销毁资源
     //2. 返回:这个返回很简单
       Map<String,Object> map = new HashMap();
        map.put("success","true");
		return JSON.toJSONString(map);
		}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值