# SOP(Simple Open Platform)

**当前版本为5.0**

👉🏻 [开发文档](https://www.yuque.com/u1604442/sop)

---

一个开放平台解决方案项目，基于dubbo实现，目标让用户快速搭建自己的开放平台。

通过简单的配置后，你的项目就具备了和支付宝开放平台的一样的接口提供能力。

SOP封装了开放平台大部分功能包括：签名验证、统一异常处理、统一返回内容 、业务参数验证（JSR-303）、秘钥管理等，未来还会实现更多功能。


## 项目特点
+ 接入方式简单，与老项目不冲突，老项目注册到注册中心，然后在方法上加上注解即可。
+ 架构松耦合，业务代码实现在各自微服务上，SOP不参与业务实现，这也是dubbo微服务体系带来的好处。
+ 扩展简单，开放平台对应的功能各自独立，可以自定义实现自己的需求，如：更改参数，更改签名规则等。

## 谁可以使用这个项目
+ 有现成的项目，想改造成开放平台供他人调用
+ 有现成的项目，想暴露其中几个接口并通过开放平台供他人调用
+ 想搭一个开放平台新项目，并结合微服务的方式去维护
+ 对开放平台感兴趣的朋友

以上情况都可以考虑使用SOP

## 例子
开放接口定义

```java
/**
 * 支付接口
 *
 * @author 六如
 */
@Api("支付接口")
public interface OpenPayment {

    /**
     * 手机网站支付接口
     *
     * @apiNote 该接口是页面跳转接口，用于生成用户访问跳转链接。
     * 请在服务端执行SDK中pageExecute方法，读取响应中的body()结果。
     * 该结果用于跳转到页面，返回到用户浏览器渲染或重定向跳转到页面。
     * 具体使用方法请参考 <a href="https://torna.cn" target="_blank">接入指南</a>
     */
    @Open("pay.trade.wap.pay")
    PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request);

}
```



接口实现

```java
/**
 * 开放接口实现
 *
 * @author 六如
 */
@DubboService(validation = "true")
public class OpenPaymentImpl implements OpenPayment {

    @Override
    public PayTradeWapPayResponse tradeWapPay(PayTradeWapPayRequest request) {
        PayTradeWapPayResponse payTradeWapPayResponse = new PayTradeWapPayResponse();
        payTradeWapPayResponse.setPageRedirectionData(UUID.randomUUID().toString());
        return payTradeWapPayResponse;
    }
}

```

调用：

```java
@Test
public void testGet() throws Exception {
    // 公共请求参数
    Map<String, String> params = new HashMap<String, String>();
    params.put("app_id", appId);
    params.put("method", "pay.trade.wap.pay");
    params.put("format", "json");
    params.put("charset", "utf-8");
    params.put("sign_type", "RSA2");
    params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    params.put("version", "1.0");
    
    // 业务参数
    Map<String, Object> bizContent = new HashMap<>();
    bizContent.put("outTradeNo", "70501111111S001111119");
    bizContent.put("totalAmount", "9.00");
    bizContent.put("subject", "衣服");
    bizContent.put("productCode", "QUICK_WAP_WAY");
    
    params.put("biz_content", JSON.toJSONString(bizContent));
    String content = AlipaySignature.getSignContent(params);
    String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
    params.put("sign", sign);
    
    System.out.println("----------- 请求信息 -----------");
    System.out.println("请求参数：" + buildParamQuery(params));
    System.out.println("商户秘钥：" + privateKey);
    System.out.println("待签名内容：" + content);
    System.out.println("签名(sign)：" + sign);
    System.out.println("URL参数：" + buildUrlQuery(params));
    
    System.out.println("----------- 返回结果 -----------");
    String responseData = postJson(url, params);// 发送请求
    System.out.println(responseData);
}
```

SDK调用

```java
@Test
public void test() {
    PayTradeWapPayRequest request = new PayTradeWapPayRequest();
    
    PayTradeWapPayModel model = new PayTradeWapPayModel();
    model.setOutTradeNo("70501111111S001111119");
    model.setTotalAmount(new BigDecimal("1000"));
    model.setSubject("衣服");
    model.setProductCode("QUICK_WAP_WAY");
    
    request.setBizModel(model);

    Result<PayTradeWapPayResponse> result = client.execute(request);
    if (result.isSuccess()) {
        PayTradeWapPayResponse response = result.getData();
        System.out.println(response);
    } else {
        System.out.println(result);
    }
}
```

## 整体架构
![整体架构](./asset/arc.jpg)

## 页面预览

- 文档页面

<img src="./asset/sop_doc.png" />

- 后台管理-文档管理

<img src="./asset/sop_admin_doc.jpg" />

- 后台管理-秘钥管理

<img src="./asset/sop_admin_secret.jpg" />

- 后台管理-用户管理

<img src="./asset/sop_admin_user.jpg" />

## 沟通交流

<img src="./asset/sop_qqgroup.jpg" width="50%" height="50%" />
