1.话不多说们直接上图:
看来看去网上都没有腾讯云市场接入java的编写可以借鉴,还是自己发一个开荒。
1. 就是一个问题 怎么接入自己得saas产品实现自己或你公司的产品售卖 ,这里以腾讯云为例,华为云 阿里云较为简单。需要小伙伴留言。
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;
@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.*;
public class TxUtils {
private TxUtils(){};
static Map<String,String> map = new HashMap<>();
public static boolean signature(Map<String,String> map){
long l = System.currentTimeMillis() / 1000;
long l1 = l - new Long(map.get("timestamp"));
if (l1>30){
return false;
}
List<String> list = new ArrayList<>();
list.add(map.get("timestamp"));
list.add(map.get("eventId"));
list.add("f1ce146677a34cac8d6754c0a2f014ff");
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();
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(item.getBytes());
byte[] digest = messageDigest.digest();
StringBuilder res = new StringBuilder();
for (byte b : digest) {
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<>();
Map<String, String[]> paramsMap = request.getParameterMap();
for (Map.Entry<String, String[]> entry : paramsMap.entrySet()) {
map.put(entry.getKey(),entry.getValue()[0]);
}
return map;
}
public static Date expireTime(Date date ,Integer time, String unit) {
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;
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){
Map<String,Object> map = new HashMap();
Map<String,String> mapInfo = new HashMap();
mapInfo.put("");
List<Map<String,String>> additionalInfo = new ArrayList<>();
map.put("signId", "");
Map<String,String> userNameMap = new HashMap();
userNameMap.put("name","账号");
userNameMap.put("value","");
additionalInfo.add(userNameMap);
Map<String,String> passNameMap = new HashMap();
passNameMap.put("name","密码");
passNameMap.put("value","");
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);
return JSON.toJSONString(map);
}
String renewInstance(AppTxOrder appTxOrder){
Map<String,Object> map = new HashMap();
map.put("success","true");
return JSON.toJSONString(map);
}
String expireInstance(AppTxOrder appTxOrder){
Map<String,Object> map = new HashMap();
map.put("success","true");
return JSON.toJSONString(map);
}
String destroyInstance(AppTxOrder appTxOrder){
Map<String,Object> map = new HashMap();
map.put("success","true");
return JSON.toJSONString(map);
}
}