feat: 增加了 openapi spec
diff --git a/payapi-common/build.gradle b/payapi-common/build.gradle
index ee97798..ba8d004 100644
--- a/payapi-common/build.gradle
+++ b/payapi-common/build.gradle
@@ -32,6 +32,11 @@
     implementation "commons-beanutils:commons-beanutils:${beanutilsVersion}"
     implementation "commons-codec:commons-codec:${codecVersion}"
     implementation "org.apache.commons:commons-lang3:${lang3Version}"
+    implementation "org.springframework:spring-web"
+    implementation group: 'io.swagger', name: 'swagger-annotations', version: swaggerVersion
+
+    implementation "org.openapitools:jackson-databind-nullable:${openapitoolsVersion}"
+
 
     compileOnly "org.projectlombok:lombok:${lombokVersion}"
     annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java
new file mode 100644
index 0000000..1f0adda
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodeFormat.java
@@ -0,0 +1,44 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * Gets or Sets QrcodeFormat
+ */
+public enum QrcodeFormat {
+  
+  PLAIN("plain"),
+  
+  BASE64("base64"),
+  
+  HEX("hex");
+
+  private String value;
+
+  QrcodeFormat(String value) {
+    this.value = value;
+  }
+
+  @Override
+  @JsonValue
+  public String toString() {
+    return String.valueOf(value);
+  }
+
+  @JsonCreator
+  public static QrcodeFormat fromValue(String value) {
+    for (QrcodeFormat b : QrcodeFormat.values()) {
+      if (b.value.equals(value)) {
+        return b;
+      }
+    }
+    throw new IllegalArgumentException("Unexpected value '" + value + "'");
+  }
+}
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
new file mode 100644
index 0000000..51685c4
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayConfirmRequest.java
@@ -0,0 +1,307 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.supwisdom.dlpay.payapi.model.QrcodeFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayConfirmRequest
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+public class QrcodePayConfirmRequest   {
+  @JsonProperty("billno")
+  private String billno;
+
+  @JsonProperty("shopaccno")
+  private String shopaccno;
+
+  @JsonProperty("transDate")
+  private String transDate;
+
+  @JsonProperty("transTime")
+  private String transTime;
+
+  @JsonProperty("dlttype")
+  private String dlttype;
+
+  @JsonProperty("amount")
+  private Integer amount;
+
+  @JsonProperty("userid")
+  private String userid;
+
+  @JsonProperty("anonymous")
+  private Boolean anonymous;
+
+  @JsonProperty("qrcode")
+  private String qrcode;
+
+  @JsonProperty("qrcodeFormat")
+  private QrcodeFormat qrcodeFormat;
+
+  public QrcodePayConfirmRequest billno(String billno) {
+    this.billno = billno;
+    return this;
+  }
+
+  /**
+   * Get billno
+   * @return billno
+  */
+  @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=16) 
+  public String getBillno() {
+    return billno;
+  }
+
+  public void setBillno(String billno) {
+    this.billno = billno;
+  }
+
+  public QrcodePayConfirmRequest shopaccno(String shopaccno) {
+    this.shopaccno = shopaccno;
+    return this;
+  }
+
+  /**
+   * Get shopaccno
+   * @return shopaccno
+  */
+  @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") 
+  public String getShopaccno() {
+    return shopaccno;
+  }
+
+  public void setShopaccno(String shopaccno) {
+    this.shopaccno = shopaccno;
+  }
+
+  public QrcodePayConfirmRequest transDate(String transDate) {
+    this.transDate = transDate;
+    return this;
+  }
+
+  /**
+   * Get transDate
+   * @return transDate
+  */
+  @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=8,max=8) 
+  public String getTransDate() {
+    return transDate;
+  }
+
+  public void setTransDate(String transDate) {
+    this.transDate = transDate;
+  }
+
+  public QrcodePayConfirmRequest transTime(String transTime) {
+    this.transTime = transTime;
+    return this;
+  }
+
+  /**
+   * Get transTime
+   * @return transTime
+  */
+  @ApiModelProperty(value = "")
+
+@Pattern(regexp="[0-9]*") @Size(min=6,max=6) 
+  public String getTransTime() {
+    return transTime;
+  }
+
+  public void setTransTime(String transTime) {
+    this.transTime = transTime;
+  }
+
+  public QrcodePayConfirmRequest dlttype(String dlttype) {
+    this.dlttype = dlttype;
+    return this;
+  }
+
+  /**
+   * Get dlttype
+   * @return dlttype
+  */
+  @ApiModelProperty(value = "")
+
+
+  public String getDlttype() {
+    return dlttype;
+  }
+
+  public void setDlttype(String dlttype) {
+    this.dlttype = dlttype;
+  }
+
+  public QrcodePayConfirmRequest amount(Integer amount) {
+    this.amount = amount;
+    return this;
+  }
+
+  /**
+   * Get amount
+   * @return amount
+  */
+  @ApiModelProperty(value = "")
+
+
+  public Integer getAmount() {
+    return amount;
+  }
+
+  public void setAmount(Integer amount) {
+    this.amount = amount;
+  }
+
+  public QrcodePayConfirmRequest userid(String userid) {
+    this.userid = userid;
+    return this;
+  }
+
+  /**
+   * Get userid
+   * @return userid
+  */
+  @ApiModelProperty(value = "")
+
+
+  public String getUserid() {
+    return userid;
+  }
+
+  public void setUserid(String userid) {
+    this.userid = userid;
+  }
+
+  public QrcodePayConfirmRequest anonymous(Boolean anonymous) {
+    this.anonymous = anonymous;
+    return this;
+  }
+
+  /**
+   * Get anonymous
+   * @return anonymous
+  */
+  @ApiModelProperty(value = "")
+
+
+  public Boolean getAnonymous() {
+    return anonymous;
+  }
+
+  public void setAnonymous(Boolean anonymous) {
+    this.anonymous = anonymous;
+  }
+
+  public QrcodePayConfirmRequest qrcode(String qrcode) {
+    this.qrcode = qrcode;
+    return this;
+  }
+
+  /**
+   * Get qrcode
+   * @return qrcode
+  */
+  @ApiModelProperty(value = "")
+
+
+  public String getQrcode() {
+    return qrcode;
+  }
+
+  public void setQrcode(String qrcode) {
+    this.qrcode = qrcode;
+  }
+
+  public QrcodePayConfirmRequest qrcodeFormat(QrcodeFormat qrcodeFormat) {
+    this.qrcodeFormat = qrcodeFormat;
+    return this;
+  }
+
+  /**
+   * Get qrcodeFormat
+   * @return qrcodeFormat
+  */
+  @ApiModelProperty(value = "")
+
+  @Valid
+
+  public QrcodeFormat getQrcodeFormat() {
+    return qrcodeFormat;
+  }
+
+  public void setQrcodeFormat(QrcodeFormat qrcodeFormat) {
+    this.qrcodeFormat = qrcodeFormat;
+  }
+
+
+  @Override
+  public boolean equals(java.lang.Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    QrcodePayConfirmRequest qrcodePayConfirmRequest = (QrcodePayConfirmRequest) o;
+    return Objects.equals(this.billno, qrcodePayConfirmRequest.billno) &&
+        Objects.equals(this.shopaccno, qrcodePayConfirmRequest.shopaccno) &&
+        Objects.equals(this.transDate, qrcodePayConfirmRequest.transDate) &&
+        Objects.equals(this.transTime, qrcodePayConfirmRequest.transTime) &&
+        Objects.equals(this.dlttype, qrcodePayConfirmRequest.dlttype) &&
+        Objects.equals(this.amount, qrcodePayConfirmRequest.amount) &&
+        Objects.equals(this.userid, qrcodePayConfirmRequest.userid) &&
+        Objects.equals(this.anonymous, qrcodePayConfirmRequest.anonymous) &&
+        Objects.equals(this.qrcode, qrcodePayConfirmRequest.qrcode) &&
+        Objects.equals(this.qrcodeFormat, qrcodePayConfirmRequest.qrcodeFormat);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(billno, shopaccno, transDate, transTime, dlttype, amount, userid, anonymous, qrcode, qrcodeFormat);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("class QrcodePayConfirmRequest {\n");
+    
+    sb.append("    billno: ").append(toIndentedString(billno)).append("\n");
+    sb.append("    shopaccno: ").append(toIndentedString(shopaccno)).append("\n");
+    sb.append("    transDate: ").append(toIndentedString(transDate)).append("\n");
+    sb.append("    transTime: ").append(toIndentedString(transTime)).append("\n");
+    sb.append("    dlttype: ").append(toIndentedString(dlttype)).append("\n");
+    sb.append("    amount: ").append(toIndentedString(amount)).append("\n");
+    sb.append("    userid: ").append(toIndentedString(userid)).append("\n");
+    sb.append("    anonymous: ").append(toIndentedString(anonymous)).append("\n");
+    sb.append("    qrcode: ").append(toIndentedString(qrcode)).append("\n");
+    sb.append("    qrcodeFormat: ").append(toIndentedString(qrcodeFormat)).append("\n");
+    sb.append("}");
+    return sb.toString();
+  }
+
+  /**
+   * Convert the given object to string with each line indented by 4 spaces
+   * (except the first line).
+   */
+  private String toIndentedString(java.lang.Object o) {
+    if (o == null) {
+      return "null";
+    }
+    return o.toString().replace("\n", "\n    ");
+  }
+}
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
new file mode 100644
index 0000000..cdb426d
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/payapi/model/QrcodePayInitRequest.java
@@ -0,0 +1,212 @@
+package com.supwisdom.dlpay.payapi.model;
+
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.supwisdom.dlpay.payapi.model.QrcodeFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.openapitools.jackson.nullable.JsonNullable;
+import javax.validation.Valid;
+import javax.validation.constraints.*;
+
+/**
+ * QrcodePayInitRequest
+ */
+@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2020-03-12T16:09:45.966+08:00[Asia/Shanghai]")
+
+public class QrcodePayInitRequest   {
+  @JsonProperty("qrcode")
+  private String qrcode;
+
+  @JsonProperty("transDate")
+  private String transDate;
+
+  @JsonProperty("transTime")
+  private String transTime;
+
+  @JsonProperty("shopaccno")
+  private String shopaccno;
+
+  @JsonProperty("billno")
+  private String billno;
+
+  @JsonProperty("qrcodeFormat")
+  private QrcodeFormat qrcodeFormat;
+
+  public QrcodePayInitRequest qrcode(String qrcode) {
+    this.qrcode = qrcode;
+    return this;
+  }
+
+  /**
+   * Get qrcode
+   * @return qrcode
+  */
+  @ApiModelProperty(required = true, value = "")
+  @NotNull
+
+
+  public String getQrcode() {
+    return qrcode;
+  }
+
+  public void setQrcode(String qrcode) {
+    this.qrcode = qrcode;
+  }
+
+  public QrcodePayInitRequest transDate(String transDate) {
+    this.transDate = transDate;
+    return this;
+  }
+
+  /**
+   * Get transDate
+   * @return transDate
+  */
+  @ApiModelProperty(required = true, value = "")
+  @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=8,max=8) 
+  public String getTransDate() {
+    return transDate;
+  }
+
+  public void setTransDate(String transDate) {
+    this.transDate = transDate;
+  }
+
+  public QrcodePayInitRequest transTime(String transTime) {
+    this.transTime = transTime;
+    return this;
+  }
+
+  /**
+   * Get transTime
+   * @return transTime
+  */
+  @ApiModelProperty(required = true, value = "")
+  @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=6,max=6) 
+  public String getTransTime() {
+    return transTime;
+  }
+
+  public void setTransTime(String transTime) {
+    this.transTime = transTime;
+  }
+
+  public QrcodePayInitRequest shopaccno(String shopaccno) {
+    this.shopaccno = shopaccno;
+    return this;
+  }
+
+  /**
+   * Get shopaccno
+   * @return shopaccno
+  */
+  @ApiModelProperty(required = true, value = "")
+  @NotNull
+
+@Pattern(regexp="[0-9]*") 
+  public String getShopaccno() {
+    return shopaccno;
+  }
+
+  public void setShopaccno(String shopaccno) {
+    this.shopaccno = shopaccno;
+  }
+
+  public QrcodePayInitRequest billno(String billno) {
+    this.billno = billno;
+    return this;
+  }
+
+  /**
+   * Get billno
+   * @return billno
+  */
+  @ApiModelProperty(required = true, value = "")
+  @NotNull
+
+@Pattern(regexp="[0-9]*") @Size(min=16) 
+  public String getBillno() {
+    return billno;
+  }
+
+  public void setBillno(String billno) {
+    this.billno = billno;
+  }
+
+  public QrcodePayInitRequest qrcodeFormat(QrcodeFormat qrcodeFormat) {
+    this.qrcodeFormat = qrcodeFormat;
+    return this;
+  }
+
+  /**
+   * Get qrcodeFormat
+   * @return qrcodeFormat
+  */
+  @ApiModelProperty(value = "")
+
+  @Valid
+
+  public QrcodeFormat getQrcodeFormat() {
+    return qrcodeFormat;
+  }
+
+  public void setQrcodeFormat(QrcodeFormat qrcodeFormat) {
+    this.qrcodeFormat = qrcodeFormat;
+  }
+
+
+  @Override
+  public boolean equals(java.lang.Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    QrcodePayInitRequest qrcodePayInitRequest = (QrcodePayInitRequest) o;
+    return Objects.equals(this.qrcode, qrcodePayInitRequest.qrcode) &&
+        Objects.equals(this.transDate, qrcodePayInitRequest.transDate) &&
+        Objects.equals(this.transTime, qrcodePayInitRequest.transTime) &&
+        Objects.equals(this.shopaccno, qrcodePayInitRequest.shopaccno) &&
+        Objects.equals(this.billno, qrcodePayInitRequest.billno) &&
+        Objects.equals(this.qrcodeFormat, qrcodePayInitRequest.qrcodeFormat);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(qrcode, transDate, transTime, shopaccno, billno, qrcodeFormat);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("class QrcodePayInitRequest {\n");
+    
+    sb.append("    qrcode: ").append(toIndentedString(qrcode)).append("\n");
+    sb.append("    transDate: ").append(toIndentedString(transDate)).append("\n");
+    sb.append("    transTime: ").append(toIndentedString(transTime)).append("\n");
+    sb.append("    shopaccno: ").append(toIndentedString(shopaccno)).append("\n");
+    sb.append("    billno: ").append(toIndentedString(billno)).append("\n");
+    sb.append("    qrcodeFormat: ").append(toIndentedString(qrcodeFormat)).append("\n");
+    sb.append("}");
+    return sb.toString();
+  }
+
+  /**
+   * Convert the given object to string with each line indented by 4 spaces
+   * (except the first line).
+   */
+  private String toIndentedString(java.lang.Object o) {
+    if (o == null) {
+      return "null";
+    }
+    return o.toString().replace("\n", "\n    ");
+  }
+}
+