diff --git a/.gitignore b/.gitignore index 6e48406..c5693ed 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ org.eclipse.jdt.core.prefs example/out .vscode .classpath +target/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e21a646..d36bfe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # ChangeLog +## 2.5.6 + +- 更新: `RequestOptions` 新增`Ping++`验签公钥设置参数 + +## 2.5.5 + +-更新: 退款 refund 新增返回 `app` 参数. + +## 2.5.4 + +- 修正: 修复版本 2.5.3 中存在的 POM 依赖问题。建议用户直接升级到此版本。 + +## 2.5.3 + +- 新增: 签约修改接口 + +## 2.5.2 + +- 修改: 正确 `Map` 以及 `List` 内的元素类型 + +## 2.5.0 + +- 新增: 响应签名验签 +- 新增: 微信扣款预扣费通知实现 +- 更新: `RequestOptions` 新增`Ping++`公钥设置参数 +- 更新: webhook验签方法移动至 `PingppSignature` 类中 +- 更新: `gson` 到`2.10`;`commons-codec` 到 `1.17.0` + ## 2.4.1 - 修改: Refund 对象新增`currency` 字段 @@ -10,12 +38,13 @@ > 本次更新有较多与旧版本不兼容的地方。 -- 修改: 支持 JDK 8 及以上; +- 修改: 支持 JDK 8 及以上; - 修改: 异常抛出修改,统一声明为 `PingppException`,实际使用可以再做具体判断; - 废弃: 原接口,支持传 `apiKey` 参数的方法,全部删除,可以用 `RequestOptions` 代替; - 新增: 每个接口最后一个参数支持 `RequestOptions`; - 新增: `PingppException` 增加 `type`、`code`、`statusCode`; -- 新增: 对象增加 `getLastResponse()` 方法,可以用于获取当前这次请求的 `response` 对象,包含 `HTTP Status Code`、`Headers`、`Response Body` 等; +- 新增: 对象增加 `getLastResponse()` 方法,可以用于获取当前这次请求的 `response` 对象,包含 `HTTP Status Code`、`Headers`、 + `Response Body` 等; - 废弃: 取消对 `PKCS1` 格式私钥的支持,请转成 `PKCS8` 再使用; --- @@ -66,25 +95,34 @@ - 移除 `PingppAccount` ## 2.3.8 (2018-05-22) + #### 新增 + - WxLiteOAuth 接口 - Agreement 接口 #### 修改 + - 合并部分内部类 - WxpubOAuth 接口错误时增加异常 ## 2.3.7 (2018-03-16) + #### 新增 + - BalanceSettlement 接口 - CardInfo 接口 ## 2.3.5 (2018-02-27) + #### 修正 + - 部分对象字段从 Integer 改成 Long ## 2.3.4 (2018-01-10) + #### 修改 + - 移除已废弃接口 - 移除 transfer、batch_transfer 取消接口 - 更新示例 @@ -92,137 +130,190 @@ - settle_account 字段更新 ## 2.3.3 (2017-12-27) + #### 修正 + - 修正 javadoc ## 2.3.2 (2017-12-21) + #### 修正 + - 兼容 JDK 1.7 ## 2.3.1 (2017-12-08) + #### 修正 + - Event 解析修正 ## 2.3.0 (2017-12-01) + #### 更改 + - 合并账户系统相关接口 ## 2.2.5 (2017-10-10) + #### 新增 + - 新增重试机制 #### 修改 + - 优化 SDK ## 2.2.4 (2017-06-19) + #### 修改 + - Charge 增加字段 reversed,表示是否已撤销 - 针对渠道 isv_scan, isv_qr_isv_wap 增加撤销方法,`Charge.reverse(CHARGE_ID)` - Refund 增加 extra 字段 ## 2.2.3 (2017-03-27) + #### 修改 + - BatchTransfer 增加字段 ## 2.2.2 (2017-03-21) + #### 修正 + - alipay_pc_direct/alipay_wap 渠道 credential 字段类型的修正 ## 2.2.1 (2017-01-13) + #### 新增 + - 添加 gradle 相关文件 - 添加部分测试文件 - batch_transfer 更新/取消接口 #### 修改 + - 更改签名私钥获取方式 - Charge.list app[id] 参数改为必传 - 红包去除多余的参数 - batch_refund charges 字段格式修改 #### 修正 + - Webhooks 解析对象 batch_refund、batch_transfer、customs 对应事件错误 ## 2.2.0 + #### 新增 + - 添加 BatchRefund、BatchTransfer、Customs #### 修改 + - 签名生成规则变更 - 列表查询接口换成 `list` 方法,代替 `all` 方法 - 退款接口调用方式变更,直接使用 Refund 对象 - Refund 对象添加 charge_order_no, transaction_no 属性 ## 2.1.9 + #### 修改 -- 添加 RateLimitException + +- 添加 RateLimitException - 兼容 http 地址,仅为方便测试 ## 2.1.8 + #### 新增 + - Identification 身份证银行卡接口 ## 2.1.7 + #### 修正 + - RedEnvelope、Transfer 添加字段 ## 2.1.6 + #### 修正 + - 签名内容编码问题 ## 2.1.5 + #### 修改 + - 补充 RedEnvelope、Transfer 缺少字段 ## 2.1.4 + #### 修改 + - 更改 content-type 为 application/json ## 2.1.3 + - 兼容两种微信公众号接入方式 ## 2.1.2 + - 补全确实字段 - 修正 Event 解析 - 修正部分字符 JSON 序列化问题 - 添加请求签名 ## 2.1.1 + - 修正 extra 类型 - 兼容 jdk 1.6 ## 2.1.0 + - 添加应用内快捷支付对应接口 ## 2.0.10 + - 增加 Refund 对象 status 字段 ## 2.0.8 + - 增加 ChannelException ## 2.0.6 + - 增加企业转账、修改红包接口 ## 2.0.5 + - 增加 event sdk ## 2.0.4 + - 更改 sdk 目录格式,修复wx_pub渠道timeStamp 类型问题。 ## 2.0.3 + - 增加 apple pay ,重写 getcredential 方法。 ## 2.0.2 + - 增加微信红包 ## 2.0.1 + #### 更改 + 修改 wx credential 里的 timeStamp 类型为字符串,防止变成科学计数法 ## 2.0.0 + #### 更改 + 添加新渠道支持:百付宝、百付宝WAP、微信公众平台 ## 1.0.4 + #### 更改: + 添加 `Expanding` 机制 diff --git a/README.md b/README.md index 554ae7a..1a8a82c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Java 要求 JDK 8 及以上。 ### 手动安装 -JAR 下载地址: [pingpp-java](https://jcenter.bintray.com/Pingplusplus/pingpp-java/) +JAR 下载地址: [pingpp-java](https://mvnrepository.com/artifact/com.pingxx/pingpp-java) 请根据版本号下载相应的 JAR 文件并导入至工程。 @@ -29,23 +29,16 @@ JAR 下载地址: [pingpp-java](https://jcenter.bintray.com/Pingplusplus/pingpp- maven 远程仓库 ``` xml - - - false - - central - bintray - https://jcenter.bintray.com - +mavenCentral ``` 安装 Ping++ SDK ``` xml - Pingplusplus + com.pingxx pingpp-java - 2.4.1 + 2.5.6 jar ``` @@ -56,16 +49,14 @@ gradle 远程仓库 ``` repositories { - maven { - url "https://jcenter.bintray.com" - } + mavenCentral() } ``` 安装 Ping++ SDK ``` -compile 'Pingplusplus:pingpp-java:2.4.1' +implementation 'com.pingxx:pingpp-java:2.5.6' ``` ## 初始化 diff --git a/VERSION b/VERSION index 005119b..1b03fe6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4.1 +2.5.6 \ No newline at end of file diff --git a/build.gradle b/build.gradle index cc365c6..e7c254d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,69 +1,12 @@ buildscript { repositories { - maven { - url 'https://maven.aliyun.com/repository/central' - } - mavenLocal() mavenCentral() } } allprojects { repositories { - maven { - url 'https://maven.aliyun.com/repository/central' - } - mavenLocal() mavenCentral() } - apply plugin: 'maven' - apply plugin: 'maven-publish' apply plugin: 'java' } - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -dependencies { - compile 'com.google.code.gson:gson:2.8.9' - compile 'commons-codec:commons-codec:1.13' - - testCompile 'junit:junit:4.12' -} - -task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier = 'javadoc' - from javadoc.destinationDir -} - -artifacts { - archives sourcesJar, javadocJar -} - -publishing { - publications { - mavenJava(MavenPublication) { - from components.java - artifact sourcesJar - artifact javadocJar - groupId 'Pingplusplus' - artifactId 'pingpp-java' - - pom.withXml { - def root = asNode() - root.appendNode('name', 'pingpp-java') - root.appendNode('url', 'https://github.com/PingPlusPlus/pingpp-java') - } - } - } -} -model { - tasks.generatePomFileForMavenJavaPublication { - destination = file("pom.xml") - } -} diff --git a/example/build.gradle b/example/build.gradle index 3c9bd78..495f667 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -1,8 +1,13 @@ apply plugin: 'java' dependencies { - compile 'com.google.code.gson:gson:2.8.5' - compile 'commons-codec:commons-codec:1.13' + implementation 'com.google.code.gson:gson:2.10' + implementation 'commons-codec:commons-codec:1.17.0' - compile project(':') + // 方法 1. 本地文件系统依赖 + // implementation fileTree(dir: 'lib', includes: ['*jar']) + // 方法 2. 仓库依赖 + // implementation 'com.pingxx:pingpp-java:2.5.6' + // 方法 3.模块依赖 + implementation project(':pingpp-sdk') } diff --git a/example/res/pingpp_public_key.pem b/example/res/pingpp_public_key.pem deleted file mode 100644 index 7cf6d7c..0000000 --- a/example/res/pingpp_public_key.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzs8SiPoFQT9K0lWa6WSx -0d6UnA391KM2aFwijY0AK7r+MiAe07ivenopzFL3dqIRhQjuP7d30V85kWydN5UZ -cm/tZgm4K+8wttb988hOrzSjtPOMghHK+bnDwE8FIB+ZbHAZCEVhNfE6i9kLGbHH -Q617+mxUTJ3yEZG9CIgke475o2Blxy4UMsRYjo2gl5aanzmOmoZcbiC/R5hXSQUH -XV9/VzA7U//DIm8Xn7rerd1n8+KWCg4hrIIu/A0FKm8zyS4QwAwQO2wdzGB0h15t -uFLhjVz1W5ZPXjmCRLzTUoAvH12C6YFStvS5kjPcA66P1nSKk5o3koSxOumOs0iC -EQIDAQAB ------END PUBLIC KEY----- diff --git a/example/src/main/java/com/pingxx/example/AgreementExample.java b/example/src/main/java/com/pingxx/example/AgreementExample.java new file mode 100644 index 0000000..205a51c --- /dev/null +++ b/example/src/main/java/com/pingxx/example/AgreementExample.java @@ -0,0 +1,30 @@ +package com.pingxx.example; + +import com.pingplusplus.exception.PingppException; +import com.pingplusplus.model.Agreement; + +import java.util.HashMap; +import java.util.Map; + +public class AgreementExample { + + private String appId; + + public AgreementExample(String appId) { + this.appId = appId; + } + + public static void runDemos(String appId) throws PingppException { + AgreementExample example = new AgreementExample(appId); + Agreement agrModify = example.modify(); + } + + public Agreement modify() throws PingppException { + String agreementId = "agr_123456"; + Map params = new HashMap<>(); + params.put("deduct_time", "2025-07-10"); + params.put("memo", "扣款失败,需延期扣款时间"); + + return Agreement.modify(agreementId, params); + } +} diff --git a/example/src/main/java/com/pingxx/example/AgreementNotifyExample.java b/example/src/main/java/com/pingxx/example/AgreementNotifyExample.java new file mode 100644 index 0000000..54c9fa5 --- /dev/null +++ b/example/src/main/java/com/pingxx/example/AgreementNotifyExample.java @@ -0,0 +1,33 @@ +package com.pingxx.example; + +import com.pingplusplus.exception.PingppException; +import com.pingplusplus.model.AgreementNotify; + +import java.util.HashMap; +import java.util.Map; + +public class AgreementNotifyExample { + private String appId; + + AgreementNotifyExample(String appId) { + this.appId = appId; + } + + public static void runDemos(String appId) { + AgreementNotifyExample example = new AgreementNotifyExample(appId); + System.out.println("------- 签约扣款-商户预扣费通知 -------"); + example.create("agr_123456"); + } + + public AgreementNotify create(String id) { + AgreementNotify agreementNotify = null; + Map params = new HashMap(); + params.put("amount", 100); + try { + agreementNotify = AgreementNotify.create(id, params); + } catch (PingppException e) { + e.printStackTrace(); + } + return agreementNotify; + } +} diff --git a/example/src/main/java/com/pingxx/example/Main.java b/example/src/main/java/com/pingxx/example/Main.java index 0e25e93..c38f9f2 100644 --- a/example/src/main/java/com/pingxx/example/Main.java +++ b/example/src/main/java/com/pingxx/example/Main.java @@ -3,6 +3,7 @@ import com.pingplusplus.Pingpp; import java.math.BigInteger; +import java.net.URL; import java.security.SecureRandom; /** @@ -30,6 +31,8 @@ public class Main { // 你生成的私钥路径 private final static String privateKeyFilePath = "res/your_rsa_private_key_pkcs8.pem"; + private final static String verifyKeyFilePath = "pingpp_public_key.pem"; + protected static String projectDir; public static void main(String[] args) throws Exception { @@ -43,12 +46,15 @@ public static void main(String[] args) throws Exception { // 设置私钥路径,用于请求签名 //Pingpp.privateKeyPath = projectDir + privateKeyFilePath; - /** + /* * 或者直接设置私钥内容 - Pingpp.privateKey = "... PKCS8私钥内容字符串 ..."; + * Pingpp.privateKey = "... PKCS8私钥内容字符串 ..."; */ Pingpp.privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHYyS3FwoESp1hGLYiBhy6k9Ag3lzGCIEvm50IIEkE0Ftc9qq44TWqyl+EHUpTMdcBOcI42JLO5stwFOfCLa3PQStEJ4llIRFEKlsrHh67pvWd5RNaSBrvGlnFY40S+SZmjk2WF/h9dE9Ric79t0YI0alD8dIl9Yu3OaEKo7VonBWFwOYMxjPhtORlq+EUF1XJd//yftQrKWTTd7KaUonWzBCl4VzFop/OyTWYlTuZz3eYJaNpH5VaQ1vDgBAcPIeBvMf7NgBHMKW6LLmFd2LEYQ/6I7hkGTjysSzWEpO8bPWT6OEsJ2R2kFGOrSkr+G2MDcJ7ykXYAmz5+A3plS6ZAgMBAAECggEAVrgwR9GlcahiOtDcpn+yDxQq+aC9CQS561LrQZWJLKbSleRS7IZHKTlLwdJbeUO8F7RfXQoVEBghc2YkRrhHWFUn1ES95VY0hElHzcET7Nn5CeuQNzwVOtljIg7iVNY4dXJ/HEDguu/Tb8tYU9FajItj60FJ/WiGk/JksJPzWsOCVPVniy9fTbTLy1e+dCpCI6OXirtm7hvbodRNDjree0wSEzm7vL0wVzEZFo6kX+ABGUwaoO7pPyH+hgyI5Iuhc65NHsHzTJpf8yNFl9QGhkxvm2Ff2oEtDt1idOTBrHB6tg+ti9Ctb2+2yzBnk14hsSYJnKitR7wM6ZCFPX4eYQKBgQD+JAREeFkodec/SC+GX+4Q4Y68uMPkfUPrMKXM4cyY5wgXk64RBvRVxIxX7x6Y3tIKn9v8tWAprbsyVr15eb4RcAFEVwjuoZixhd9sIPsRhfdNolKn/fSPIsHL4ywcJMSIt7KVKHuQeqBNHy0o0PxQjNej1ozsmrAWqV55cbKHswKBgQDI2JQRTPIEC/2y6LdmBVhGJW9OKWTYdVNjq7rX+Yw4uxOtfd5hBqpvgZEklKEk72aazFdEcERlAm9SqoX09qk6zK/wcq4Xn5Q/qy8ecmjuyf2AK9X+HUdMerMVxhK9RpeevKYP/RO2F/wIN64anlQVYygVkXXgdOvWhBE4YABKgwKBgDRtmbPGYB5ItHwJmERQZfx1i8zDESaB8RED6DBsJJkmkDTM8ovws1c+RPWfDuDalto6QFfR0xTGEmhAHLaCtwNB6AEBM4aHL8jvpTfZVfI3gN0zL3oYmestcG1vYBouO504yE6dG2Ci6479b4OMGYFEjPfvuwLUpp8GMcc7/WihAoGANCp8mtm/ammq5VMof2kX+nAyrrx1ovsmQ5cRGpOIZhvBCqjMn6rZjci7aCLqj+tWXRKCABagzROK0o/T50JBxjHv6KYArcYW/Up7HI9ezdbM7wNzu2LjZ+veo+MkbuDs9J/PCgwTmJI2NfQwVl2VPVDZ0nBLi5cSwk7fIiNdL/0CgYEAtECmC1QDs53Di2MIsa/Fe4sWfJGSDqEWqhcA/aPwf1skM6VJJXBBMV1qFtwgO1AlLnu9dQYra6ylsUoubVYIXM9XK7EMhbqi57+Q75jHFTc0DnzOTyho5Gp4Ddi8dztmZGNWdWTGdeMqh+svqMXkD6VdJeddyGu/Zlgj7Wk6whU="; + //(可选,推荐设置)设置响应验证公钥,用于验证响应是否真实有效;不设置或设置密钥错误将不验签 + Pingpp.setVerifyPublicKeyPath(getResPath(verifyKeyFilePath)); + // Charge 示例 ChargeExample.runDemos(appId); @@ -80,15 +86,26 @@ public static void main(String[] args) throws Exception { // 报关 // 请使用 live key 调用该接口 CustomsExample.runDemos(appId); + + //签约代扣示例 + AgreementExample.runDemos(appId); } - private static SecureRandom random = new SecureRandom(); + private static final SecureRandom random = new SecureRandom(); public static String randomString(int length) { String str = new BigInteger(130, random).toString(32); return str.substring(0, length); } + public static String getResPath(String subPath) { + if (subPath == null) { + throw new NullPointerException(); + } + URL resource = Thread.currentThread().getContextClassLoader().getResource(subPath); + return resource != null ? resource.getPath() : subPath; + } + public static int currentTimeSeconds() { return (int) (System.currentTimeMillis() / 1000); } diff --git a/example/src/main/java/com/pingxx/example/WebhooksVerifyExample.java b/example/src/main/java/com/pingxx/example/WebhooksVerifyExample.java index 31af3fe..891e1ed 100644 --- a/example/src/main/java/com/pingxx/example/WebhooksVerifyExample.java +++ b/example/src/main/java/com/pingxx/example/WebhooksVerifyExample.java @@ -7,37 +7,25 @@ */ package com.pingxx.example; -import java.io.*; -import java.security.InvalidKeyException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.Signature; -import java.security.SignatureException; -import java.security.spec.X509EncodedKeySpec; - -import org.apache.commons.codec.binary.Base64; +import com.pingplusplus.Pingpp; +import com.pingplusplus.net.APIResource; +import com.pingplusplus.util.PingppSignature; /** - * Created by sunkai on 15/5/19. webhooks 验证签名示例 - * + * webhooks 验证签名示例 + *

* 该实例演示如何对 Ping++ webhooks 通知进行验证。 * 验证是为了让开发者确认该通知来自 Ping++ ,防止恶意伪造通知。用户如果有别的验证机制,可以不进行验证签名。 - * + *

* 验证签名需要 签名、公钥、验证信息,该实例采用文件存储方式进行演示。 * 实际项目中,需要用户从异步通知的 HTTP header 中读取签名,从 HTTP body 中读取验证信息。公钥的存储方式也需要用户自行设定。 - * - * 该实例仅供演示如何验证签名,请务必不要直接 copy 到实际项目中使用。 - * + *

+ * 该实例仅供演示如何验证签名,请务必不要直接 copy 到实际项目中使用。 */ public class WebhooksVerifyExample { - - private static String pubKeyPath = "res/pingpp_public_key.pem"; - private static String eventPath = "res/webhooks_raw_post_data.json"; - private static String signPath = "res/signature.txt"; - /** * 验证 webhooks 签名,仅供参考 + * * @param args * @throws Exception */ @@ -46,78 +34,17 @@ public static void main(String[] args) throws Exception { } public static void runDemos() throws Exception { + String verifyPublicKey = Pingpp.verifyPublicKey; // 该数据请从 request 中获取原始 POST 请求数据, 以下仅作为示例 - String webhooksRawPostData = getStringFromFile(eventPath); + String webhooksRawPostData = "{\"id\":\"evt_400240816160755820469807\",\"created\":1723795675,\"livemode\":false,\"type\":\"charge.succeeded\",\"data\":{\"object\":{\"id\":\"ch_100240816592822384640019\",\"object\":\"charge\",\"created\":1723795492,\"livemode\":false,\"paid\":true,\"refunded\":false,\"reversed\":false,\"app\":\"app_eTC8yLuj9GSSL0yv\",\"channel\":\"wx_pub\",\"order_no\":\"1723795491985uqclqj7\",\"client_ip\":\"127.0.0.1\",\"amount\":100,\"amount_settle\":100,\"currency\":\"cny\",\"subject\":\"Your Subject\",\"body\":\"Your Body\",\"extra\":{\"open_id\":\"o7xEMsySBFG3MVHI-9VsAJX-j50W\",\"limit_pay\":\"no_credit\",\"bank_type\":\"your bank type\"},\"time_paid\":1723795675,\"time_expire\":1723802692,\"time_settle\":null,\"transaction_no\":\"1290362656202408163243920572\",\"refunds\":{\"object\":\"list\",\"url\":\"/v1/charges/ch_100240816592822384640019/refunds\",\"has_more\":false,\"data\":[]},\"amount_refunded\":0,\"failure_code\":null,\"failure_msg\":null,\"metadata\":{},\"credential\":{},\"description\":null}},\"object\":\"event\",\"request\":\"iar_mrrvj9ivPOaHPOi9aLPWPqvT\",\"pending_webhooks\":0}"; System.out.println("------- POST 原始数据 -------"); System.out.println(webhooksRawPostData); // 签名数据请从 request 的 header 中获取, key 为 X-Pingplusplus-Signature (请忽略大小写, 建议自己做格式化) - String signature = getStringFromFile(signPath); + String signature = "Ju5ItDM9Hblkm6Pbb/r3G9iM58oCtAUJlJDrOud0E23TUtGBxKYJSMcuTFbPgLGLKy5QHYovJJojjMjM1CMGCp82F+SOY1U2zuwzkAk0lVqhfQk+CWGpcyUzOtLOOblKidyuIb+axZDTIg4kK/JoOR2xMH3+cJD9BN6rtfzEDbHqyZIfv6n3y/LdZNhsXfQq+qoIRuLdHrFexk1USgk7SXFvH1pCOIt8o2+dryp/ixlNj1vGq57eE8sbEzPo72vxLtzPazlgR+67cS1bUxjzObh7YFbSSTJxkHDEIi3ipTpoiI7Kc5ng7EzsWgp3cAl7on5HztfFLfT8+Bjpdvtr6w=="; System.out.println("------- 签名 -------"); System.out.println(signature); - boolean result = verifyData(webhooksRawPostData, signature, getPubKey()); + boolean result = PingppSignature.verify(signature, webhooksRawPostData, verifyPublicKey, APIResource.CHARSET.name()); System.out.println("验签结果:" + (result ? "通过" : "失败")); } - - /** - * 读取文件, 部署 web 程序的时候, 签名和验签内容需要从 request 中获得 - * @param filePath - * @return - * @throws Exception - */ - public static String getStringFromFile(String filePath) throws Exception { - FileInputStream in = new FileInputStream(Main.projectDir + filePath); - InputStreamReader inReader = new InputStreamReader(in, "UTF-8"); - BufferedReader bf = new BufferedReader(inReader); - StringBuilder sb = new StringBuilder(); - String line; - do { - line = bf.readLine(); - if (line != null) { - if (sb.length() != 0) { - sb.append("\n"); - } - sb.append(line); - } - } while (line != null); - - return sb.toString(); - } - - /** - * 获得公钥 - * @return - * @throws Exception - */ - public static PublicKey getPubKey() throws Exception { - String pubKeyString = getStringFromFile(pubKeyPath); - pubKeyString = pubKeyString.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", ""); - byte[] keyBytes = Base64.decodeBase64(pubKeyString.getBytes("UTF-8")); - - // generate public key - X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - - return keyFactory.generatePublic(spec); - } - - /** - * 验证签名 - * @param dataString - * @param signatureString - * @param publicKey - * @return - * @throws NoSuchAlgorithmException - * @throws InvalidKeyException - * @throws SignatureException - */ - public static boolean verifyData(String dataString, String signatureString, PublicKey publicKey) - throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException { - byte[] signatureBytes = Base64.decodeBase64(signatureString); - Signature signature = Signature.getInstance("SHA256withRSA"); - signature.initVerify(publicKey); - signature.update(dataString.getBytes("UTF-8")); - return signature.verify(signatureBytes); - } - } diff --git a/example/src/main/resources/pingpp_public_key.pem b/example/src/main/resources/pingpp_public_key.pem new file mode 100644 index 0000000..c0f5d19 --- /dev/null +++ b/example/src/main/resources/pingpp_public_key.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCJqcTaGUab0vBZSkGNE1AaGiY +RcbPd7QdCQuM8EpbEpEQGr9/NjbJHCLd3eaUmYM0vy34Wux+VHnw4ckiDfBuW6/Z +fIo5GBRCI/nZLOnWcOX98ZAXYnn/VVJXuBtHtHL8DWEbYmMp+Gl4k1rFSuQKk52k +YLXeFJZJV8CBV5jA+wIDAQAB +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7b83409..68566cb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip +distributionUrl=https\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.6-all.zip diff --git a/libs/pingpp-sdk-2.5.3.jar b/libs/pingpp-sdk-2.5.3.jar new file mode 100644 index 0000000..72f00e6 Binary files /dev/null and b/libs/pingpp-sdk-2.5.3.jar differ diff --git a/pingpp-sdk/build.gradle b/pingpp-sdk/build.gradle new file mode 100644 index 0000000..cd44911 --- /dev/null +++ b/pingpp-sdk/build.gradle @@ -0,0 +1,52 @@ +buildscript { + repositories { + maven { + url 'https://maven.aliyun.com/repository/central' + } + mavenLocal() + mavenCentral() + } +} + +plugins { + id "maven-publish" + id "java" +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +configurations { + compileOnly { + extendsFrom annotationProcessor + } + testCompileOnly { + extendsFrom testAnnotationProcessor + } +} + +dependencies { + implementation 'com.google.code.gson:gson:2.10' + implementation 'commons-codec:commons-codec:1.17.0' + testImplementation 'junit:junit:4.13.2' +} + +java { + withSourcesJar() +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } + } + } + } +} \ No newline at end of file diff --git a/pingpp-sdk/pom.xml b/pingpp-sdk/pom.xml new file mode 100644 index 0000000..ab60a11 --- /dev/null +++ b/pingpp-sdk/pom.xml @@ -0,0 +1,123 @@ + + + 4.0.0 + + com.pingxx + pingpp-java + 2.5.6 + jar + + pingpp-java + A Java SDK for Ping++ Payment API. + https://github.com/PingPlusPlus/pingpp-java + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + + scm:git:https://github.com/PingPlusPlus/pingpp-java.git + + + + afon + Afon + xufeng.weng@pingxx.com + + + + + 1.8 + 1.8 + + + + + com.google.code.gson + gson + 2.10.1 + compile + + + commons-codec + commons-codec + 1.17.0 + compile + + + junit + junit + 4.13.2 + test + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.3.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.11.2 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.8 + + + sign-artifacts + verify + + sign + + + ${gpg.keyname} + ${gpg.passphrase} + + --pinentry-mode + loopback + + + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.8.0 + true + + central + true + + + + + diff --git a/src/main/java/com/pingplusplus/Pingpp.java b/pingpp-sdk/src/main/java/com/pingplusplus/Pingpp.java similarity index 79% rename from src/main/java/com/pingplusplus/Pingpp.java rename to pingpp-sdk/src/main/java/com/pingplusplus/Pingpp.java index aa5d5c0..444f8b4 100644 --- a/src/main/java/com/pingplusplus/Pingpp.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/Pingpp.java @@ -1,5 +1,11 @@ package com.pingplusplus; +import com.pingplusplus.net.APIResource; +import com.pingplusplus.util.StreamUtils; + +import java.io.FileInputStream; +import java.io.IOException; + /** * Ping++ Base class */ @@ -11,7 +17,7 @@ public abstract class Pingpp { /** * version */ - public static final String VERSION = "2.4.1"; + public static final String VERSION = "2.5.6"; /** * api key */ @@ -24,6 +30,7 @@ public abstract class Pingpp { private static volatile String apiBase = LIVE_API_BASE; public static volatile String privateKey; + public static volatile String verifyPublicKey; public static volatile String privateKeyPath; public static Boolean DEBUG = false; @@ -99,7 +106,6 @@ public static int getReadTimeout() { /** * 设置数据读取超时时间 (毫秒) - * * 不同接口的耗时时间不一样,部分接口的耗时可能比较长。 * * @param timeout timeout value in milliseconds @@ -133,4 +139,23 @@ public static String getAcceptLanguage() { public static void setAcceptLanguage(String acceptLanguage) { Pingpp.acceptLanguage = acceptLanguage; } + + public static void setVerifyPublicKeyPath(String keyFilePath) throws IOException { + Pingpp.verifyPublicKey = readKeyFromFilePath(keyFilePath); + } + + /** + * 读取密钥文件 + * + * @param filePath 文件路径 + * @return 密钥内容 + * @throws IOException IO 异常 + */ + private static String readKeyFromFilePath(String filePath) throws IOException { + FileInputStream inputStream = new FileInputStream(filePath); + String privateKey = StreamUtils.readToEnd(inputStream, APIResource.CHARSET); + inputStream.close(); + + return privateKey; + } } diff --git a/src/main/java/com/pingplusplus/exception/APIConnectionException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/APIConnectionException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/APIConnectionException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/APIConnectionException.java diff --git a/src/main/java/com/pingplusplus/exception/APIException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/APIException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/APIException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/APIException.java diff --git a/src/main/java/com/pingplusplus/exception/AuthenticationException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/AuthenticationException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/AuthenticationException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/AuthenticationException.java diff --git a/src/main/java/com/pingplusplus/exception/ChannelException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/ChannelException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/ChannelException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/ChannelException.java diff --git a/src/main/java/com/pingplusplus/exception/InvalidRequestException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/InvalidRequestException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/InvalidRequestException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/InvalidRequestException.java diff --git a/src/main/java/com/pingplusplus/exception/PingppException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/PingppException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/PingppException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/PingppException.java diff --git a/src/main/java/com/pingplusplus/exception/RateLimitException.java b/pingpp-sdk/src/main/java/com/pingplusplus/exception/RateLimitException.java similarity index 100% rename from src/main/java/com/pingplusplus/exception/RateLimitException.java rename to pingpp-sdk/src/main/java/com/pingplusplus/exception/RateLimitException.java diff --git a/src/main/java/com/pingplusplus/model/Agreement.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Agreement.java similarity index 89% rename from src/main/java/com/pingplusplus/model/Agreement.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Agreement.java index 42a6f9d..ae64880 100644 --- a/src/main/java/com/pingplusplus/model/Agreement.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/model/Agreement.java @@ -3,6 +3,7 @@ import com.pingplusplus.exception.PingppException; import com.pingplusplus.net.APIResource; import com.pingplusplus.net.RequestOptions; + import java.util.HashMap; import java.util.Map; @@ -190,6 +191,8 @@ public static Agreement retrieve(String id) throws PingppException { return retrieve(id, null); } + + /** * 查询签约(agreement) * @@ -251,4 +254,27 @@ public static Agreement cancel(String id, RequestOptions options) throws PingppE params.put("status", "canceled"); return APIResource.request(RequestMethod.PUT, instanceURL(Agreement.class, id), params, Agreement.class, options); } + + /** + * 签约修改 + * @param id + * @param params + * @param options + * @return + * @throws PingppException + */ + public static Agreement modify(String id,Map params, RequestOptions options) throws PingppException { + return APIResource.request(RequestMethod.POST, String.format("%s/%s/modify/", classURL(Agreement.class), id), params, Agreement.class, options); + } + + /** + * 签约修改 + * @param id + * @param params + * @return + * @throws PingppException + */ + public static Agreement modify(String id, Map params) throws PingppException { + return modify(id, params, null); + } } diff --git a/src/main/java/com/pingplusplus/model/AgreementCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/AgreementCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/AgreementCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/AgreementCollection.java diff --git a/pingpp-sdk/src/main/java/com/pingplusplus/model/AgreementNotify.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/AgreementNotify.java new file mode 100644 index 0000000..9fd9970 --- /dev/null +++ b/pingpp-sdk/src/main/java/com/pingplusplus/model/AgreementNotify.java @@ -0,0 +1,44 @@ +package com.pingplusplus.model; + +import com.pingplusplus.exception.PingppException; +import com.pingplusplus.net.APIResource; +import com.pingplusplus.net.RequestOptions; + +import java.util.Map; + +public class AgreementNotify extends APIResource { + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Boolean getSucceed() { + return succeed; + } + + public void setSucceed(Boolean succeed) { + this.succeed = succeed; + } + + String id; + Boolean succeed; + + public static AgreementNotify create(String id, Map params) throws PingppException { + return create(id, params, null); + } + + /** + * 签约扣款-商户预扣费通知 + * @param agreementId + * @param params + * @param options + * @return + * @throws PingppException + */ + public static AgreementNotify create(String agreementId, Map params, RequestOptions options) throws PingppException { + return APIResource.request(APIResource.RequestMethod.POST, String.format("%s/notify", instanceURL(Agreement.class, agreementId)), params, AgreementNotify.class, options); + } +} diff --git a/src/main/java/com/pingplusplus/model/App.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/App.java similarity index 100% rename from src/main/java/com/pingplusplus/model/App.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/App.java diff --git a/src/main/java/com/pingplusplus/model/BalanceBonus.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceBonus.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceBonus.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceBonus.java diff --git a/src/main/java/com/pingplusplus/model/BalanceBonusCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceBonusCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceBonusCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceBonusCollection.java diff --git a/src/main/java/com/pingplusplus/model/BalanceSettlement.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceSettlement.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceSettlement.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceSettlement.java diff --git a/src/main/java/com/pingplusplus/model/BalanceSettlementCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceSettlementCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceSettlementCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceSettlementCollection.java diff --git a/src/main/java/com/pingplusplus/model/BalanceTransaction.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransaction.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceTransaction.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransaction.java diff --git a/src/main/java/com/pingplusplus/model/BalanceTransactionCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransactionCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceTransactionCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransactionCollection.java diff --git a/src/main/java/com/pingplusplus/model/BalanceTransfer.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransfer.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceTransfer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransfer.java diff --git a/src/main/java/com/pingplusplus/model/BalanceTransferCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransferCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BalanceTransferCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BalanceTransferCollection.java diff --git a/src/main/java/com/pingplusplus/model/BatchRefund.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefund.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchRefund.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefund.java diff --git a/src/main/java/com/pingplusplus/model/BatchRefundCharges.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefundCharges.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchRefundCharges.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefundCharges.java diff --git a/src/main/java/com/pingplusplus/model/BatchRefundCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefundCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchRefundCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchRefundCollection.java diff --git a/src/main/java/com/pingplusplus/model/BatchTransfer.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransfer.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchTransfer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransfer.java diff --git a/src/main/java/com/pingplusplus/model/BatchTransferCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransferCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchTransferCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransferCollection.java diff --git a/src/main/java/com/pingplusplus/model/BatchTransferRecipient.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransferRecipient.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchTransferRecipient.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchTransferRecipient.java diff --git a/src/main/java/com/pingplusplus/model/BatchWithdrawal.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchWithdrawal.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchWithdrawal.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchWithdrawal.java diff --git a/src/main/java/com/pingplusplus/model/BatchWithdrawalCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/BatchWithdrawalCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/BatchWithdrawalCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/BatchWithdrawalCollection.java diff --git a/src/main/java/com/pingplusplus/model/CardInfo.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CardInfo.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CardInfo.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CardInfo.java diff --git a/src/main/java/com/pingplusplus/model/Channel.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Channel.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Channel.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Channel.java diff --git a/src/main/java/com/pingplusplus/model/Charge.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Charge.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Charge.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Charge.java diff --git a/src/main/java/com/pingplusplus/model/ChargeCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/ChargeCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeCollection.java diff --git a/src/main/java/com/pingplusplus/model/ChargeEssentials.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeEssentials.java similarity index 100% rename from src/main/java/com/pingplusplus/model/ChargeEssentials.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeEssentials.java diff --git a/src/main/java/com/pingplusplus/model/ChargeRefundCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeRefundCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/ChargeRefundCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/ChargeRefundCollection.java diff --git a/src/main/java/com/pingplusplus/model/Contact.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Contact.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Contact.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Contact.java diff --git a/src/main/java/com/pingplusplus/model/Coupon.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Coupon.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Coupon.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Coupon.java diff --git a/src/main/java/com/pingplusplus/model/CouponCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CouponCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CouponCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CouponCollection.java diff --git a/src/main/java/com/pingplusplus/model/CouponTemplate.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplate.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CouponTemplate.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplate.java diff --git a/src/main/java/com/pingplusplus/model/CouponTemplateCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplateCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CouponTemplateCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplateCollection.java diff --git a/src/main/java/com/pingplusplus/model/CouponTemplateExpiration.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplateExpiration.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CouponTemplateExpiration.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CouponTemplateExpiration.java diff --git a/src/main/java/com/pingplusplus/model/Customs.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Customs.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Customs.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Customs.java diff --git a/src/main/java/com/pingplusplus/model/CustomsCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/CustomsCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/CustomsCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/CustomsCollection.java diff --git a/src/main/java/com/pingplusplus/model/DeleteRoyaltyTemplate.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeleteRoyaltyTemplate.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeleteRoyaltyTemplate.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeleteRoyaltyTemplate.java diff --git a/src/main/java/com/pingplusplus/model/DeletedChannel.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedChannel.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedChannel.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedChannel.java diff --git a/src/main/java/com/pingplusplus/model/DeletedCoupon.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedCoupon.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedCoupon.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedCoupon.java diff --git a/src/main/java/com/pingplusplus/model/DeletedCouponTemplate.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedCouponTemplate.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedCouponTemplate.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedCouponTemplate.java diff --git a/src/main/java/com/pingplusplus/model/DeletedObjectBase.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedObjectBase.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedObjectBase.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedObjectBase.java diff --git a/src/main/java/com/pingplusplus/model/DeletedPingppObject.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedPingppObject.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedPingppObject.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedPingppObject.java diff --git a/src/main/java/com/pingplusplus/model/DeletedSettleAccount.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSettleAccount.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedSettleAccount.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSettleAccount.java diff --git a/src/main/java/com/pingplusplus/model/DeletedSplitReceiver.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSplitReceiver.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedSplitReceiver.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSplitReceiver.java diff --git a/src/main/java/com/pingplusplus/model/DeletedSubApp.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSubApp.java similarity index 100% rename from src/main/java/com/pingplusplus/model/DeletedSubApp.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/DeletedSubApp.java diff --git a/src/main/java/com/pingplusplus/model/Event.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Event.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Event.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Event.java diff --git a/src/main/java/com/pingplusplus/model/EventCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/EventCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/EventCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/EventCollection.java diff --git a/src/main/java/com/pingplusplus/model/EventData.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/EventData.java similarity index 100% rename from src/main/java/com/pingplusplus/model/EventData.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/EventData.java diff --git a/src/main/java/com/pingplusplus/model/Identification.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Identification.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Identification.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Identification.java diff --git a/src/main/java/com/pingplusplus/model/Order.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Order.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Order.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Order.java diff --git a/src/main/java/com/pingplusplus/model/OrderCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/OrderCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/OrderCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/OrderCollection.java diff --git a/src/main/java/com/pingplusplus/model/OrderRefund.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/OrderRefund.java similarity index 100% rename from src/main/java/com/pingplusplus/model/OrderRefund.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/OrderRefund.java diff --git a/src/main/java/com/pingplusplus/model/OrderRefundCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/OrderRefundCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/OrderRefundCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/OrderRefundCollection.java diff --git a/src/main/java/com/pingplusplus/model/PingppCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppCollection.java diff --git a/src/main/java/com/pingplusplus/model/PingppCollectionAPIResource.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppCollectionAPIResource.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppCollectionAPIResource.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppCollectionAPIResource.java diff --git a/src/main/java/com/pingplusplus/model/PingppError.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppError.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppError.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppError.java diff --git a/src/main/java/com/pingplusplus/model/PingppObject.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppObject.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppObject.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppObject.java diff --git a/src/main/java/com/pingplusplus/model/PingppObjectInterface.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppObjectInterface.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppObjectInterface.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppObjectInterface.java diff --git a/src/main/java/com/pingplusplus/model/PingppRawJsonObject.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/PingppRawJsonObject.java similarity index 100% rename from src/main/java/com/pingplusplus/model/PingppRawJsonObject.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/PingppRawJsonObject.java diff --git a/src/main/java/com/pingplusplus/model/ProfitTransaction.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/ProfitTransaction.java similarity index 100% rename from src/main/java/com/pingplusplus/model/ProfitTransaction.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/ProfitTransaction.java diff --git a/src/main/java/com/pingplusplus/model/ProfitTransactionCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/ProfitTransactionCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/ProfitTransactionCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/ProfitTransactionCollection.java diff --git a/src/main/java/com/pingplusplus/model/Recharge.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Recharge.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Recharge.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Recharge.java diff --git a/src/main/java/com/pingplusplus/model/RechargeCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RechargeCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeCollection.java diff --git a/src/main/java/com/pingplusplus/model/RechargeRefund.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeRefund.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RechargeRefund.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeRefund.java diff --git a/src/main/java/com/pingplusplus/model/RechargeRefundCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeRefundCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RechargeRefundCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RechargeRefundCollection.java diff --git a/src/main/java/com/pingplusplus/model/RedEnvelope.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RedEnvelope.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RedEnvelope.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RedEnvelope.java diff --git a/src/main/java/com/pingplusplus/model/RedEnvelopeCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RedEnvelopeCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RedEnvelopeCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RedEnvelopeCollection.java diff --git a/src/main/java/com/pingplusplus/model/Refund.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Refund.java similarity index 97% rename from src/main/java/com/pingplusplus/model/Refund.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Refund.java index fa94d1d..9120769 100644 --- a/src/main/java/com/pingplusplus/model/Refund.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/model/Refund.java @@ -8,6 +8,7 @@ public class Refund extends APIResource { String id; + String app; String object; String orderNo; Integer amount; @@ -175,6 +176,14 @@ public String getCurrency() { public void setCurrency(String currency) { this.currency = currency; } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } /** * 创建 refund * diff --git a/src/main/java/com/pingplusplus/model/Royalty.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Royalty.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Royalty.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Royalty.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyCollection.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyDataResult.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyDataResult.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyDataResult.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyDataResult.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltySettlement.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltySettlement.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltySettlement.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltySettlement.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltySettlementCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltySettlementCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltySettlementCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltySettlementCollection.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyTemplate.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTemplate.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyTemplate.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTemplate.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyTemplateCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTemplateCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyTemplateCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTemplateCollection.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyTransaction.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTransaction.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyTransaction.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTransaction.java diff --git a/src/main/java/com/pingplusplus/model/RoyaltyTransactionCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTransactionCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/RoyaltyTransactionCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/RoyaltyTransactionCollection.java diff --git a/src/main/java/com/pingplusplus/model/SettleAccount.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccount.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SettleAccount.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccount.java diff --git a/src/main/java/com/pingplusplus/model/SettleAccountCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccountCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SettleAccountCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccountCollection.java diff --git a/src/main/java/com/pingplusplus/model/SettleAccountRecipient.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccountRecipient.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SettleAccountRecipient.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SettleAccountRecipient.java diff --git a/src/main/java/com/pingplusplus/model/SplitProfit.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfit.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SplitProfit.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfit.java diff --git a/src/main/java/com/pingplusplus/model/SplitProfitCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfitCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SplitProfitCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfitCollection.java diff --git a/src/main/java/com/pingplusplus/model/SplitProfitRecipient.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfitRecipient.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SplitProfitRecipient.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SplitProfitRecipient.java diff --git a/src/main/java/com/pingplusplus/model/SplitReceiver.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SplitReceiver.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SplitReceiver.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SplitReceiver.java diff --git a/src/main/java/com/pingplusplus/model/SplitReceiverCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SplitReceiverCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SplitReceiverCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SplitReceiverCollection.java diff --git a/src/main/java/com/pingplusplus/model/SubApp.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SubApp.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SubApp.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SubApp.java diff --git a/src/main/java/com/pingplusplus/model/SubAppCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SubAppCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SubAppCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SubAppCollection.java diff --git a/src/main/java/com/pingplusplus/model/SubBank.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SubBank.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SubBank.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SubBank.java diff --git a/src/main/java/com/pingplusplus/model/SubBankCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/SubBankCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/SubBankCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/SubBankCollection.java diff --git a/src/main/java/com/pingplusplus/model/Summary.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Summary.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Summary.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Summary.java diff --git a/src/main/java/com/pingplusplus/model/Transfer.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Transfer.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Transfer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Transfer.java diff --git a/src/main/java/com/pingplusplus/model/TransferCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/TransferCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/TransferCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/TransferCollection.java diff --git a/src/main/java/com/pingplusplus/model/User.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/User.java similarity index 100% rename from src/main/java/com/pingplusplus/model/User.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/User.java diff --git a/src/main/java/com/pingplusplus/model/UserCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/UserCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/UserCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/UserCollection.java diff --git a/src/main/java/com/pingplusplus/model/UserPic.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/UserPic.java similarity index 100% rename from src/main/java/com/pingplusplus/model/UserPic.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/UserPic.java diff --git a/src/main/java/com/pingplusplus/model/Webhooks.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Webhooks.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Webhooks.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Webhooks.java diff --git a/src/main/java/com/pingplusplus/model/Withdrawal.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/Withdrawal.java similarity index 100% rename from src/main/java/com/pingplusplus/model/Withdrawal.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/Withdrawal.java diff --git a/src/main/java/com/pingplusplus/model/WithdrawalCollection.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/WithdrawalCollection.java similarity index 100% rename from src/main/java/com/pingplusplus/model/WithdrawalCollection.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/WithdrawalCollection.java diff --git a/src/main/java/com/pingplusplus/model/WithdrawalCollectionBase.java b/pingpp-sdk/src/main/java/com/pingplusplus/model/WithdrawalCollectionBase.java similarity index 100% rename from src/main/java/com/pingplusplus/model/WithdrawalCollectionBase.java rename to pingpp-sdk/src/main/java/com/pingplusplus/model/WithdrawalCollectionBase.java diff --git a/src/main/java/com/pingplusplus/net/APIResource.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/APIResource.java similarity index 97% rename from src/main/java/com/pingplusplus/net/APIResource.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/APIResource.java index aa7b48f..10bcb6c 100644 --- a/src/main/java/com/pingplusplus/net/APIResource.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/net/APIResource.java @@ -3,9 +3,9 @@ import com.google.gson.*; import com.pingplusplus.Pingpp; import com.pingplusplus.exception.*; -import com.pingplusplus.exception.InvalidRequestException; import com.pingplusplus.model.*; import com.pingplusplus.serializer.*; +import com.pingplusplus.util.GsonUtils; import java.io.*; import java.lang.reflect.InvocationTargetException; @@ -41,8 +41,7 @@ protected enum RequestMethod { /** * Gson object use to transform json string to resource object */ - public static final Gson GSON = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + public static final Gson GSON = GsonUtils.baseGsonBuilder() .registerTypeAdapter(Charge.class, new ChargeDeserializer()) .registerTypeAdapter(RedEnvelope.class, new RedEnvelopeDeserializer()) .registerTypeAdapter(Transfer.class, new TransferDeserializer()) diff --git a/src/main/java/com/pingplusplus/net/AppBasedResource.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/AppBasedResource.java similarity index 100% rename from src/main/java/com/pingplusplus/net/AppBasedResource.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/AppBasedResource.java diff --git a/src/main/java/com/pingplusplus/net/HttpClient.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/HttpClient.java similarity index 100% rename from src/main/java/com/pingplusplus/net/HttpClient.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/HttpClient.java diff --git a/src/main/java/com/pingplusplus/net/HttpContent.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/HttpContent.java similarity index 100% rename from src/main/java/com/pingplusplus/net/HttpContent.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/HttpContent.java diff --git a/src/main/java/com/pingplusplus/net/HttpHeaders.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/HttpHeaders.java similarity index 100% rename from src/main/java/com/pingplusplus/net/HttpHeaders.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/HttpHeaders.java diff --git a/src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java similarity index 87% rename from src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java index af39110..41d2bcd 100644 --- a/src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/net/HttpURLConnectionClient.java @@ -2,6 +2,8 @@ import com.pingplusplus.Pingpp; import com.pingplusplus.exception.APIConnectionException; +import com.pingplusplus.exception.AuthenticationException; +import com.pingplusplus.util.PingppSignature; import com.pingplusplus.util.StreamUtils; import com.pingplusplus.util.StringUtils; @@ -37,6 +39,10 @@ public PingppResponse request(PingppRequest request) throws APIConnectionExcepti if (responseCode >= 200 && responseCode < 300) { responseBody = StreamUtils.readToEnd(conn.getInputStream(), APIResource.CHARSET); + boolean verified = PingppSignature.verify(headers, responseBody, request.options.getVerifyPublicKey(), APIResource.CHARSET.name()); + if (!verified) { + throw new AuthenticationException("响应签名验证失败,请检查验签公钥是否正确"); + } } else { responseBody = StreamUtils.readToEnd(conn.getErrorStream(), APIResource.CHARSET); } @@ -49,6 +55,8 @@ public PingppResponse request(PingppRequest request) throws APIConnectionExcepti + "Please check your internet connection and try again.", Pingpp.getApiBase(), e.getMessage()), e); + } catch (AuthenticationException e) { + throw new RuntimeException(e); } finally { if (conn != null) { conn.disconnect(); diff --git a/src/main/java/com/pingplusplus/net/PingppRequest.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/PingppRequest.java similarity index 100% rename from src/main/java/com/pingplusplus/net/PingppRequest.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/PingppRequest.java diff --git a/src/main/java/com/pingplusplus/net/PingppResponse.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/PingppResponse.java similarity index 100% rename from src/main/java/com/pingplusplus/net/PingppResponse.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/PingppResponse.java diff --git a/src/main/java/com/pingplusplus/net/RequestOptions.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/RequestOptions.java similarity index 84% rename from src/main/java/com/pingplusplus/net/RequestOptions.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/RequestOptions.java index 4257b47..7a2b165 100644 --- a/src/main/java/com/pingplusplus/net/RequestOptions.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/net/RequestOptions.java @@ -6,6 +6,7 @@ public class RequestOptions { private final String apiKey; private final String appId; private final String privateKey; + private final String verifyPublicKey; private final int connectTimeout; private final int readTimeout; @@ -19,6 +20,7 @@ public static RequestOptions getDefault() { Pingpp.apiKey, Pingpp.appId, Pingpp.privateKey, + Pingpp.verifyPublicKey, Pingpp.getConnectTimeout(), Pingpp.getReadTimeout(), Pingpp.getMaxNetworkRetries(), @@ -29,6 +31,7 @@ private RequestOptions( String apiKey, String appId, String privateKey, + String verifyPublicKey, int connectTimeout, int readTimeout, int maxNetworkRetries, @@ -36,6 +39,7 @@ private RequestOptions( this.apiKey = apiKey; this.appId = appId; this.privateKey = privateKey; + this.verifyPublicKey = verifyPublicKey; this.connectTimeout = connectTimeout; this.readTimeout = readTimeout; this.maxNetworkRetries = maxNetworkRetries; @@ -70,6 +74,8 @@ public String getAcceptLanguage() { return acceptLanguage; } + public String getVerifyPublicKey() {return verifyPublicKey;} + public static RequestOptionsBuilder builder() { return new RequestOptionsBuilder(); } @@ -83,10 +89,22 @@ public static final class RequestOptionsBuilder { private int maxNetworkRetries; private String acceptLanguage; + public String getVerifyPublicKey() { + return verifyPublicKey; + } + + public RequestOptionsBuilder setVerifyPublicKey(String verifyPublicKey) { + this.verifyPublicKey = normalizePublicVerifyKey(verifyPublicKey); + return this; + } + + private String verifyPublicKey; + public RequestOptionsBuilder() { this.apiKey = Pingpp.apiKey; this.appId = Pingpp.appId; this.privateKey = Pingpp.privateKey; + this.verifyPublicKey = Pingpp.verifyPublicKey; this.connectTimeout = Pingpp.getConnectTimeout(); this.readTimeout = Pingpp.getReadTimeout(); this.maxNetworkRetries = Pingpp.getMaxNetworkRetries(); @@ -125,6 +143,11 @@ public RequestOptionsBuilder setPrivateKey(String privateKey) { return this; } + public RequestOptionsBuilder clearVerifyPublicKey() { + this.verifyPublicKey = null; + return this; + } + public RequestOptionsBuilder clearAppId() { this.appId = null; return this; @@ -171,6 +194,7 @@ public RequestOptions build() { normalizeApiKey(this.apiKey), normalizeAppId(this.appId), normalizePrivateKey(this.privateKey), + normalizePublicVerifyKey(this.verifyPublicKey), connectTimeout, readTimeout, maxNetworkRetries, @@ -214,6 +238,17 @@ private static String normalizePrivateKey(String privateKey) { return normalized; } + private static String normalizePublicVerifyKey(String verifyPublicKey) { + if (verifyPublicKey == null) { + return null; + } + String normalized = verifyPublicKey.trim(); + if (normalized.isEmpty()) { + throw new InvalidRequestOptionsException("Empty publicVerifyKey specified!"); + } + return normalized; + } + private static String normalizeAcceptLanguage(String acceptLanguage) { // null acceptLanguage are considered "valid" if (acceptLanguage == null) { diff --git a/src/main/java/com/pingplusplus/net/SubAppBasedResource.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/SubAppBasedResource.java similarity index 100% rename from src/main/java/com/pingplusplus/net/SubAppBasedResource.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/SubAppBasedResource.java diff --git a/src/main/java/com/pingplusplus/net/UserBasedResource.java b/pingpp-sdk/src/main/java/com/pingplusplus/net/UserBasedResource.java similarity index 100% rename from src/main/java/com/pingplusplus/net/UserBasedResource.java rename to pingpp-sdk/src/main/java/com/pingplusplus/net/UserBasedResource.java diff --git a/src/main/java/com/pingplusplus/serializer/BatchRefundChargesSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/BatchRefundChargesSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/BatchRefundChargesSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/BatchRefundChargesSerializer.java diff --git a/src/main/java/com/pingplusplus/serializer/BatchTransferRecipientSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/BatchTransferRecipientSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/BatchTransferRecipientSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/BatchTransferRecipientSerializer.java diff --git a/src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java similarity index 78% rename from src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java index 6043e2c..15ee2e3 100644 --- a/src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeDeserializer.java @@ -1,8 +1,6 @@ package com.pingplusplus.serializer; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,6 +9,7 @@ import com.pingplusplus.model.App; import com.pingplusplus.model.Charge; import com.pingplusplus.model.ChargeRefundCollection; +import com.pingplusplus.util.GsonUtils; import java.lang.reflect.Type; @@ -20,40 +19,41 @@ public class ChargeDeserializer implements JsonDeserializer { @Override - public Charge deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { - + public Charge deserialize(JsonElement jsonElement, + Type type, + JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { JsonObject chargeJson = jsonElement.getAsJsonObject(); if (null != chargeJson.getAsJsonObject("credential")) { JsonObject credentialJson = chargeJson.getAsJsonObject("credential"); JsonObject channelCredential; if (credentialJson.getAsJsonObject("wx") != null) { JsonObject wx = credentialJson.getAsJsonObject("wx"); - Long timeStamp = wx.get("timeStamp").getAsLong(); + long timeStamp = wx.get("timeStamp").getAsLong(); wx.addProperty("timeStamp", Long.toString(timeStamp)); } else if (credentialJson.getAsJsonObject("wx_pub") != null) { JsonObject wxPub = credentialJson.getAsJsonObject("wx_pub"); if (null == wxPub.get("signed_data") && wxPub.get("timeStamp") != null) { - Long timeStamp = wxPub.get("timeStamp").getAsLong(); + long timeStamp = wxPub.get("timeStamp").getAsLong(); wxPub.addProperty("timeStamp", Long.toString(timeStamp)); } } else if ((channelCredential = credentialJson.getAsJsonObject("bfb")) != null || (channelCredential = credentialJson.getAsJsonObject("bfb_wap")) != null) { if (channelCredential.has("total_amount")) { - Long total_amount = channelCredential.get("total_amount").getAsLong(); + long total_amount = channelCredential.get("total_amount").getAsLong(); channelCredential.addProperty("total_amount", Long.toString(total_amount)); } } else if ((channelCredential = credentialJson.getAsJsonObject("alipay")) != null || (channelCredential = credentialJson.getAsJsonObject("alipay_wap")) != null || (channelCredential = credentialJson.getAsJsonObject("alipay_pc_direct")) != null) { if (channelCredential.has("payment_type")) { - Long paymentType = channelCredential.get("payment_type").getAsLong(); + long paymentType = channelCredential.get("payment_type").getAsLong(); channelCredential.addProperty("payment_type", Long.toString(paymentType)); } } } - Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES). - registerTypeAdapter(ChargeRefundCollection.class, new ChargeRefundCollectionDeserializer()) + Gson gson = GsonUtils.baseGsonBuilder() + .registerTypeAdapter(ChargeRefundCollection.class, new ChargeRefundCollectionDeserializer()) .create(); JsonElement appElement = chargeJson.get("app"); Charge charge = gson.fromJson(jsonElement, Charge.class); diff --git a/src/main/java/com/pingplusplus/serializer/ChargeEssentialsSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeEssentialsSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/ChargeEssentialsSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeEssentialsSerializer.java diff --git a/src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java similarity index 65% rename from src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java index 8b1231a..48616ac 100644 --- a/src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ChargeRefundCollectionDeserializer.java @@ -1,26 +1,20 @@ package com.pingplusplus.serializer; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; -import com.google.gson.reflect.TypeToken; import com.pingplusplus.model.ChargeRefundCollection; -import com.pingplusplus.model.Refund; +import com.pingplusplus.util.GsonUtils; import java.lang.reflect.Type; -import java.util.List; public class ChargeRefundCollectionDeserializer implements JsonDeserializer { public ChargeRefundCollection deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); + Gson gson = GsonUtils.baseGsonBuilder().create(); return gson.fromJson(json, typeOfT); } diff --git a/src/main/java/com/pingplusplus/serializer/CouponTemplateExpirationSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/CouponTemplateExpirationSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/CouponTemplateExpirationSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/CouponTemplateExpirationSerializer.java diff --git a/src/main/java/com/pingplusplus/serializer/DoubleTypeSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/DoubleTypeSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/DoubleTypeSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/DoubleTypeSerializer.java diff --git a/src/main/java/com/pingplusplus/serializer/EventDataDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/EventDataDeserializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/EventDataDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/EventDataDeserializer.java diff --git a/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ObjectListDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ObjectListDeserializer.java new file mode 100644 index 0000000..134ba36 --- /dev/null +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/ObjectListDeserializer.java @@ -0,0 +1,49 @@ +package com.pingplusplus.serializer; + +import com.google.gson.*; +import com.pingplusplus.util.GsonUtils; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; + +public class ObjectListDeserializer implements JsonDeserializer> { + + @Override + public List deserialize(JsonElement elem, + Type type, + JsonDeserializationContext context) { + List list = new ArrayList<>(); + JsonArray jsonArray = elem.getAsJsonArray(); + + for (JsonElement element : jsonArray) { + if (element.isJsonNull()) { + list.add(null); + } else if (element.isJsonPrimitive()) { + JsonPrimitive primitive = element.getAsJsonPrimitive(); + if (primitive.isNumber()) { + String numStr = primitive.getAsString(); + if (numStr.contains(".")) { + list.add(primitive.getAsDouble()); + } else { + try { + list.add(primitive.getAsLong()); + } catch (NumberFormatException e) { + list.add(primitive.getAsBigDecimal()); + } + } + } else if (primitive.isString()) { + list.add(primitive.getAsString()); + } else if (primitive.isBoolean()) { + list.add(primitive.getAsBoolean()); + } + } else if (element.isJsonArray()) { + list.add(context.deserialize(element, GsonUtils.LIST_OBJ)); + } else if (element.isJsonObject()) { + list.add(context.deserialize(element, GsonUtils.MAP_STR_OBJ)); + } + } + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/com/pingplusplus/serializer/PingppRawJsonObjectDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/PingppRawJsonObjectDeserializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/PingppRawJsonObjectDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/PingppRawJsonObjectDeserializer.java diff --git a/src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java similarity index 79% rename from src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java index e2b6ee9..251279b 100644 --- a/src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/RedEnvelopeDeserializer.java @@ -1,8 +1,6 @@ package com.pingplusplus.serializer; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,6 +9,7 @@ import com.pingplusplus.model.App; import com.pingplusplus.model.ChargeRefundCollection; import com.pingplusplus.model.RedEnvelope; +import com.pingplusplus.util.GsonUtils; import java.lang.reflect.Type; @@ -21,8 +20,8 @@ public class RedEnvelopeDeserializer implements JsonDeserializer { @Override public RedEnvelope deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject transFerJson = json.getAsJsonObject(); - Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES). - registerTypeAdapter(ChargeRefundCollection.class, new ChargeRefundCollectionDeserializer()) + Gson gson = GsonUtils.baseGsonBuilder() + .registerTypeAdapter(ChargeRefundCollection.class, new ChargeRefundCollectionDeserializer()) .create(); JsonElement appElement = transFerJson.get("app"); RedEnvelope redEnvelope = gson.fromJson(json, RedEnvelope.class); diff --git a/src/main/java/com/pingplusplus/serializer/SettleAccountRecipientSerializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/SettleAccountRecipientSerializer.java similarity index 100% rename from src/main/java/com/pingplusplus/serializer/SettleAccountRecipientSerializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/SettleAccountRecipientSerializer.java diff --git a/pingpp-sdk/src/main/java/com/pingplusplus/serializer/StringObjectMapDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/StringObjectMapDeserializer.java new file mode 100644 index 0000000..42ad230 --- /dev/null +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/StringObjectMapDeserializer.java @@ -0,0 +1,52 @@ +package com.pingplusplus.serializer; + +import com.google.gson.*; +import com.pingplusplus.util.GsonUtils; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +public class StringObjectMapDeserializer implements JsonDeserializer> { + + @Override + public Map deserialize(JsonElement elem, + Type type, + JsonDeserializationContext context) { + Map map = new HashMap<>(); + JsonObject jsonObject = elem.getAsJsonObject(); + + for (Map.Entry entry : jsonObject.entrySet()) { + String key = entry.getKey(); + JsonElement value = entry.getValue(); + + if (value.isJsonNull()) { + map.put(key, null); + } else if (value.isJsonPrimitive()) { + JsonPrimitive primitive = value.getAsJsonPrimitive(); + if (primitive.isNumber()) { + String numStr = primitive.getAsString(); + if (numStr.contains(".")) { + map.put(key, primitive.getAsDouble()); + } else { + try { + map.put(key, primitive.getAsLong()); + } catch (NumberFormatException e) { + map.put(key, primitive.getAsBigDecimal()); + } + } + } else if (primitive.isString()) { + map.put(key, primitive.getAsString()); + } else if (primitive.isBoolean()) { + map.put(key, primitive.getAsBoolean()); + } + } else if (value.isJsonArray()) { + map.put(key, context.deserialize(value, GsonUtils.LIST_OBJ)); + } else if (value.isJsonObject()) { + map.put(key, context.deserialize(value, GsonUtils.MAP_STR_OBJ)); + } + } + + return map; + } +} \ No newline at end of file diff --git a/src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java similarity index 84% rename from src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java index e3aa75a..a137464 100644 --- a/src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/SubAppDeserializer.java @@ -2,6 +2,7 @@ import com.google.gson.*; import com.pingplusplus.model.*; +import com.pingplusplus.util.GsonUtils; import java.lang.reflect.Type; @@ -16,9 +17,7 @@ public SubApp deserialize(JsonElement jsonElement, Type type, JsonDeserializatio JsonObject subAppJson = jsonElement.getAsJsonObject(); - Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); + Gson gson = GsonUtils.baseGsonBuilder().create(); JsonElement userElement = subAppJson.get("user"); SubApp subApp = gson.fromJson(jsonElement, SubApp.class); diff --git a/src/main/java/com/pingplusplus/serializer/TransferDeserializer.java b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/TransferDeserializer.java similarity index 86% rename from src/main/java/com/pingplusplus/serializer/TransferDeserializer.java rename to pingpp-sdk/src/main/java/com/pingplusplus/serializer/TransferDeserializer.java index cc7812f..c0ed8d9 100644 --- a/src/main/java/com/pingplusplus/serializer/TransferDeserializer.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/serializer/TransferDeserializer.java @@ -1,8 +1,6 @@ package com.pingplusplus.serializer; -import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -11,6 +9,7 @@ import com.pingplusplus.model.App; import com.pingplusplus.model.ChargeRefundCollection; import com.pingplusplus.model.Transfer; +import com.pingplusplus.util.GsonUtils; import java.lang.reflect.Type; @@ -22,7 +21,7 @@ public class TransferDeserializer implements JsonDeserializer { public Transfer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject transFerJson = json.getAsJsonObject(); - Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + Gson gson = GsonUtils.baseGsonBuilder() .registerTypeAdapter(ChargeRefundCollection.class, new ChargeRefundCollectionDeserializer()) .create(); JsonElement appElement = transFerJson.get("app"); diff --git a/src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java similarity index 90% rename from src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java rename to pingpp-sdk/src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java index aadfaa0..15f13cb 100644 --- a/src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/util/CaseInsensitiveMap.java @@ -82,17 +82,17 @@ public void clear() { @Override public Set keySet() { - return this.store.values().stream().map(entry -> entry.getKey()).collect(Collectors.toSet()); + return this.store.values().stream().map(Entry::getKey).collect(Collectors.toSet()); } @Override public Collection values() { - return this.store.values().stream().map(entry -> entry.getValue()).collect(Collectors.toList()); + return this.store.values().stream().map(Entry::getValue).collect(Collectors.toList()); } @Override public Set> entrySet() { - return this.store.values().stream().collect(Collectors.toSet()); + return new HashSet<>(this.store.values()); } // Utility diff --git a/pingpp-sdk/src/main/java/com/pingplusplus/util/GsonUtils.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/GsonUtils.java new file mode 100644 index 0000000..6187708 --- /dev/null +++ b/pingpp-sdk/src/main/java/com/pingplusplus/util/GsonUtils.java @@ -0,0 +1,25 @@ +package com.pingplusplus.util; + +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.pingplusplus.serializer.ObjectListDeserializer; +import com.pingplusplus.serializer.StringObjectMapDeserializer; + +public final class GsonUtils { + public static final Type MAP_STR_OBJ = new TypeToken>() {}.getType(); + public static final Type LIST_OBJ = new TypeToken>() {}.getType(); + + private GsonUtils() {} + + public static GsonBuilder baseGsonBuilder() { + return new GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .registerTypeAdapter(GsonUtils.MAP_STR_OBJ, new StringObjectMapDeserializer()) + .registerTypeAdapter(GsonUtils.LIST_OBJ, new ObjectListDeserializer()); + } +} diff --git a/pingpp-sdk/src/main/java/com/pingplusplus/util/PingppSignature.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/PingppSignature.java new file mode 100644 index 0000000..a1db312 --- /dev/null +++ b/pingpp-sdk/src/main/java/com/pingplusplus/util/PingppSignature.java @@ -0,0 +1,150 @@ +package com.pingplusplus.util; + +import com.pingplusplus.Pingpp; +import com.pingplusplus.exception.AuthenticationException; +import com.pingplusplus.net.HttpHeaders; +import org.apache.commons.codec.binary.Base64; + +import java.io.UnsupportedEncodingException; +import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * Created by Afon on 2016/12/16. + */ +public class PingppSignature { + public static String sign(String data, String PEMEncodedPrivateKey, String charset) { + PrivateKey privateKey = getPrivateKeyFromPEM(PEMEncodedPrivateKey); + if (privateKey == null) { + return null; + } + + try { + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initSign(privateKey); + signature.update(data.getBytes(charset)); + byte[] signBytes = signature.sign(); + + return Base64.encodeBase64String(signBytes).replaceAll("[\n\r]", ""); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return null; + } + + /** + * webhook verify + * @param encodedSign + * @param data + * @param PEMEncodedPublicKey + * @param charset + * @return + * @throws AuthenticationException + */ + public static boolean verify(String encodedSign, String data, String PEMEncodedPublicKey, String charset) throws AuthenticationException { + if (StringUtils.isBlank(PEMEncodedPublicKey)) { + return true; + } + PublicKey publicKey = getPublicKeyFromPEM(PEMEncodedPublicKey); + if (publicKey == null) { + return true; + } + if (StringUtils.isBlank(encodedSign)) { + throw new AuthenticationException("响应签名 (X-Pingplusplus-Signature) 为空"); + } + try { + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(publicKey); + signature.update(data.getBytes(charset)); + return signature.verify(Base64.decodeBase64(encodedSign)); + } catch (InvalidKeyException | UnsupportedEncodingException | SignatureException | NoSuchAlgorithmException e) { + if (Pingpp.DEBUG) { + e.printStackTrace(); + } + return false; + } + } + + public static boolean verify(HttpHeaders headers, String data, String PEMEncodedPublicKey, String charset) throws AuthenticationException { + if (StringUtils.isBlank(PEMEncodedPublicKey)) { + return true; + } + PublicKey publicKey = getPublicKeyFromPEM(PEMEncodedPublicKey); + if (publicKey == null) { + return true; + } + if (!headers.firstValue("X-Pingplusplus-Signature").isPresent()) { + throw new AuthenticationException("响应签名 (X-Pingplusplus-Signature) 为空"); + } + String encodedSign = headers.firstValue("X-Pingplusplus-Signature").get(); + try { + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initVerify(publicKey); + signature.update(data.getBytes(charset)); + return signature.verify(Base64.decodeBase64(encodedSign)); + } catch (InvalidKeyException | UnsupportedEncodingException | SignatureException | NoSuchAlgorithmException e) { + if (Pingpp.DEBUG) { + e.printStackTrace(); + } + return false; + } + } + + + public static PrivateKey getPrivateKeyFromPEM(String PEMEncodedPrivateKey) { + PEMEncodedPrivateKey = PEMEncodedPrivateKey + .replaceAll("(-+BEGIN (RSA )?PRIVATE KEY-+\\r?\\n|-+END (RSA )?PRIVATE KEY-+\\r?\\n?)", ""); + byte[] privateKeyBytes = Base64.decodeBase64(PEMEncodedPrivateKey); + + try { + return generatePrivateKeyWithPKCS8(privateKeyBytes); + } catch (InvalidKeySpecException e) { + if (Pingpp.DEBUG) { + e.printStackTrace(); + } + return null; + } + } + + public static PrivateKey generatePrivateKeyWithPKCS8(byte[] privateKeyBytes) + throws InvalidKeySpecException { + try { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(keySpec); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + public static PublicKey getPublicKeyFromPEM(String PEMEncodedPublicKey) { + PEMEncodedPublicKey = PEMEncodedPublicKey + .replaceAll("(-+BEGIN (RSA )?PUBLIC KEY-+\\r?\\n|-+END (RSA )?PUBLIC KEY-+\\r?\\n?)", ""); + byte[] publicKeyBytes = Base64.decodeBase64(PEMEncodedPublicKey); + + try { + return generatePublicKey(publicKeyBytes); + } catch (InvalidKeySpecException e) { + if (Pingpp.DEBUG) { + e.printStackTrace(); + } + return null; + } + } + + public static PublicKey generatePublicKey(byte[] publicKeyBytes) + throws InvalidKeySpecException { + try { + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePublic(keySpec); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/com/pingplusplus/util/StreamUtils.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/StreamUtils.java similarity index 100% rename from src/main/java/com/pingplusplus/util/StreamUtils.java rename to pingpp-sdk/src/main/java/com/pingplusplus/util/StreamUtils.java diff --git a/src/main/java/com/pingplusplus/util/StringUtils.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/StringUtils.java similarity index 68% rename from src/main/java/com/pingplusplus/util/StringUtils.java rename to pingpp-sdk/src/main/java/com/pingplusplus/util/StringUtils.java index 790145d..ef6ce39 100644 --- a/src/main/java/com/pingplusplus/util/StringUtils.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/util/StringUtils.java @@ -35,4 +35,25 @@ public static String join(String separator, List input) { return sb.toString(); } + + /** + * 是否为空 + * + * @param cs 字符串 + * @return 空 {@code true}; 非空 {@code false}. + */ + public static boolean isBlank(final CharSequence cs) { + if (cs == null) { + return true; + } + int l = cs.length(); + if (l > 0) { + for (int i = 0; i < l; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + } + return true; + } } diff --git a/src/main/java/com/pingplusplus/util/WxLiteOAuth.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/WxLiteOAuth.java similarity index 100% rename from src/main/java/com/pingplusplus/util/WxLiteOAuth.java rename to pingpp-sdk/src/main/java/com/pingplusplus/util/WxLiteOAuth.java diff --git a/src/main/java/com/pingplusplus/util/WxpubOAuth.java b/pingpp-sdk/src/main/java/com/pingplusplus/util/WxpubOAuth.java similarity index 95% rename from src/main/java/com/pingplusplus/util/WxpubOAuth.java rename to pingpp-sdk/src/main/java/com/pingplusplus/util/WxpubOAuth.java index d4aeced..d6a7815 100644 --- a/src/main/java/com/pingplusplus/util/WxpubOAuth.java +++ b/pingpp-sdk/src/main/java/com/pingplusplus/util/WxpubOAuth.java @@ -1,10 +1,12 @@ package com.pingplusplus.util; -import com.google.gson.*; +import com.google.gson.FieldNamingPolicy; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.pingplusplus.exception.ChannelException; import java.io.BufferedReader; -import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; @@ -157,8 +159,7 @@ public static String getJsapiTicket(String appId, String appSecret) throws Unsup String queryString = WxpubOAuth.httpBuildQuery(data); String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?" + queryString; String resp = httpGet(accessTokenUrl); - JsonParser jp = new JsonParser(); - JsonObject respJson = jp.parse(resp).getAsJsonObject(); + JsonObject respJson = JsonParser.parseString(resp).getAsJsonObject(); if (respJson.has("errcode")) { return respJson.toString(); } @@ -169,7 +170,7 @@ public static String getJsapiTicket(String appId, String appSecret) throws Unsup queryString = WxpubOAuth.httpBuildQuery(data); String jsapiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?" + queryString; resp = httpGet(jsapiTicketUrl); - JsonObject ticket = jp.parse(resp).getAsJsonObject(); + JsonObject ticket = JsonParser.parseString(resp).getAsJsonObject(); return ticket.get("ticket").getAsString(); } @@ -183,8 +184,7 @@ public static String getJsapiTicket(String appId, String appSecret) throws Unsup public static String getSignature(String charge, String jsapiTicket, String url) { if (null == charge || null == jsapiTicket || charge.isEmpty() || jsapiTicket.isEmpty()) return null; - JsonParser jp = new JsonParser(); - JsonObject chargeJson = jp.parse(charge).getAsJsonObject(); + JsonObject chargeJson = JsonParser.parseString(charge).getAsJsonObject(); if (!chargeJson.has("credential")) { return null; } @@ -206,9 +206,7 @@ public static String getSignature(String charge, String jsapiTicket, String url) crypt.reset(); crypt.update(string1.getBytes(CHARSET)); signature = byteToHex(crypt.digest()); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (UnsupportedEncodingException e) { + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/src/test/java/com/pingplusplus/CardInfoTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/CardInfoTest.java similarity index 100% rename from src/test/java/com/pingplusplus/CardInfoTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/CardInfoTest.java diff --git a/src/test/java/com/pingplusplus/PingppTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/PingppTest.java similarity index 82% rename from src/test/java/com/pingplusplus/PingppTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/PingppTest.java index 3ff1e7e..368100a 100644 --- a/src/test/java/com/pingplusplus/PingppTest.java +++ b/pingpp-sdk/src/test/java/com/pingplusplus/PingppTest.java @@ -2,6 +2,7 @@ import com.pingplusplus.exception.PingppException; import com.pingplusplus.model.*; +import com.pingplusplus.net.APIResource; import org.junit.BeforeClass; import org.junit.Test; @@ -25,12 +26,55 @@ public class PingppTest { Pingpp.DEBUG = true; } + @Test public void testDeserialize() { + String jsonStr = "{\n" + + " \"id\": \"ch_1234567890\",\n" + + " \"object\": \"charge\",\n" + + " \"livemode\": true,\n" + + " \"paid\": true,\n" + + " \"refunded\": true,\n" + + " \"extra\": {\n" + + " \"discount_code\": \"ABCD\",\n" + + " \"discount_amount\": 20,\n" + + " \"score\": 60.12\n" + + " },\n" + + " \"time_paid\": 1732609210,\n" + + " \"time_expire\": 1732610502,\n" + + " \"time_settle\": null,\n" + + " \"transaction_no\": \"6523236536624\",\n" + + " \"amount_refunded\": 0,\n" + + " \"failure_code\": null,\n" + + " \"failure_msg\": null,\n" + + " \"metadata\": {\n" + + " \"code\": \"10000\",\n" + + " \"type\": \"PAYMENT\",\n" + + " \"list\": [10, 100, 1000]" + + " },\n" + + " \"credential\": {},\n" + + " \"description\": \"DESC\"\n" + + "}"; + Charge ch = APIResource.getGson().fromJson(jsonStr, Charge.class); + Object discountAmount = ch.getExtra().get("discount_amount"); + assertEquals(Long.class, discountAmount.getClass()); + assertEquals(20L, discountAmount); + Object score = ch.getExtra().get("score"); + assertEquals(Double.class, score.getClass()); + System.out.println("score value: " + score); + + Object metaCode = ch.getMetadata().get("code"); + assertEquals(String.class, metaCode.getClass()); + Object metaList = ch.getMetadata().get("list"); + assertEquals(ArrayList.class, metaList.getClass()); + Object metaListEle = ((ArrayList) metaList).get(0); + assertEquals(Long.class, metaListEle.getClass()); + } + @Test public void testSetApiKey() { assertEquals("apiKey should be set", "sk_test_ibbTe5jLGCi5rzfH4OqPW9KC", Pingpp.apiKey); } @Test public void testVerifyVersions() { - assertEquals("Pingpp.VERSION should match", "2.4.1", Pingpp.VERSION); + assertEquals("Pingpp.VERSION should match", "2.5.6", Pingpp.VERSION); } @Test public void testCreateCharge() { diff --git a/src/test/java/com/pingplusplus/PingppTestBase.java b/pingpp-sdk/src/test/java/com/pingplusplus/PingppTestBase.java similarity index 100% rename from src/test/java/com/pingplusplus/PingppTestBase.java rename to pingpp-sdk/src/test/java/com/pingplusplus/PingppTestBase.java diff --git a/src/test/java/com/pingplusplus/PingppTestData.java b/pingpp-sdk/src/test/java/com/pingplusplus/PingppTestData.java similarity index 77% rename from src/test/java/com/pingplusplus/PingppTestData.java rename to pingpp-sdk/src/test/java/com/pingplusplus/PingppTestData.java index a701fe3..815aa81 100644 --- a/src/test/java/com/pingplusplus/PingppTestData.java +++ b/pingpp-sdk/src/test/java/com/pingplusplus/PingppTestData.java @@ -18,34 +18,7 @@ public static String getAppID() { } public static String getPKCS8PrivateKey() { - return "-----BEGIN PRIVATE KEY-----\n" + - "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHYyS3FwoESp1h\n" + - "GLYiBhy6k9Ag3lzGCIEvm50IIEkE0Ftc9qq44TWqyl+EHUpTMdcBOcI42JLO5stw\n" + - "FOfCLa3PQStEJ4llIRFEKlsrHh67pvWd5RNaSBrvGlnFY40S+SZmjk2WF/h9dE9R\n" + - "ic79t0YI0alD8dIl9Yu3OaEKo7VonBWFwOYMxjPhtORlq+EUF1XJd//yftQrKWTT\n" + - "d7KaUonWzBCl4VzFop/OyTWYlTuZz3eYJaNpH5VaQ1vDgBAcPIeBvMf7NgBHMKW6\n" + - "LLmFd2LEYQ/6I7hkGTjysSzWEpO8bPWT6OEsJ2R2kFGOrSkr+G2MDcJ7ykXYAmz5\n" + - "+A3plS6ZAgMBAAECggEAVrgwR9GlcahiOtDcpn+yDxQq+aC9CQS561LrQZWJLKbS\n" + - "leRS7IZHKTlLwdJbeUO8F7RfXQoVEBghc2YkRrhHWFUn1ES95VY0hElHzcET7Nn5\n" + - "CeuQNzwVOtljIg7iVNY4dXJ/HEDguu/Tb8tYU9FajItj60FJ/WiGk/JksJPzWsOC\n" + - "VPVniy9fTbTLy1e+dCpCI6OXirtm7hvbodRNDjree0wSEzm7vL0wVzEZFo6kX+AB\n" + - "GUwaoO7pPyH+hgyI5Iuhc65NHsHzTJpf8yNFl9QGhkxvm2Ff2oEtDt1idOTBrHB6\n" + - "tg+ti9Ctb2+2yzBnk14hsSYJnKitR7wM6ZCFPX4eYQKBgQD+JAREeFkodec/SC+G\n" + - "X+4Q4Y68uMPkfUPrMKXM4cyY5wgXk64RBvRVxIxX7x6Y3tIKn9v8tWAprbsyVr15\n" + - "eb4RcAFEVwjuoZixhd9sIPsRhfdNolKn/fSPIsHL4ywcJMSIt7KVKHuQeqBNHy0o\n" + - "0PxQjNej1ozsmrAWqV55cbKHswKBgQDI2JQRTPIEC/2y6LdmBVhGJW9OKWTYdVNj\n" + - "q7rX+Yw4uxOtfd5hBqpvgZEklKEk72aazFdEcERlAm9SqoX09qk6zK/wcq4Xn5Q/\n" + - "qy8ecmjuyf2AK9X+HUdMerMVxhK9RpeevKYP/RO2F/wIN64anlQVYygVkXXgdOvW\n" + - "hBE4YABKgwKBgDRtmbPGYB5ItHwJmERQZfx1i8zDESaB8RED6DBsJJkmkDTM8ovw\n" + - "s1c+RPWfDuDalto6QFfR0xTGEmhAHLaCtwNB6AEBM4aHL8jvpTfZVfI3gN0zL3oY\n" + - "mestcG1vYBouO504yE6dG2Ci6479b4OMGYFEjPfvuwLUpp8GMcc7/WihAoGANCp8\n" + - "mtm/ammq5VMof2kX+nAyrrx1ovsmQ5cRGpOIZhvBCqjMn6rZjci7aCLqj+tWXRKC\n" + - "ABagzROK0o/T50JBxjHv6KYArcYW/Up7HI9ezdbM7wNzu2LjZ+veo+MkbuDs9J/P\n" + - "CgwTmJI2NfQwVl2VPVDZ0nBLi5cSwk7fIiNdL/0CgYEAtECmC1QDs53Di2MIsa/F\n" + - "e4sWfJGSDqEWqhcA/aPwf1skM6VJJXBBMV1qFtwgO1AlLnu9dQYra6ylsUoubVYI\n" + - "XM9XK7EMhbqi57+Q75jHFTc0DnzOTyho5Gp4Ddi8dztmZGNWdWTGdeMqh+svqMXk\n" + - "D6VdJeddyGu/Zlgj7Wk6whU=\n" + - "-----END PRIVATE KEY-----"; + return "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHYyS3FwoESp1hGLYiBhy6k9Ag3lzGCIEvm50IIEkE0Ftc9qq44TWqyl+EHUpTMdcBOcI42JLO5stwFOfCLa3PQStEJ4llIRFEKlsrHh67pvWd5RNaSBrvGlnFY40S+SZmjk2WF/h9dE9Ric79t0YI0alD8dIl9Yu3OaEKo7VonBWFwOYMxjPhtORlq+EUF1XJd//yftQrKWTTd7KaUonWzBCl4VzFop/OyTWYlTuZz3eYJaNpH5VaQ1vDgBAcPIeBvMf7NgBHMKW6LLmFd2LEYQ/6I7hkGTjysSzWEpO8bPWT6OEsJ2R2kFGOrSkr+G2MDcJ7ykXYAmz5+A3plS6ZAgMBAAECggEAVrgwR9GlcahiOtDcpn+yDxQq+aC9CQS561LrQZWJLKbSleRS7IZHKTlLwdJbeUO8F7RfXQoVEBghc2YkRrhHWFUn1ES95VY0hElHzcET7Nn5CeuQNzwVOtljIg7iVNY4dXJ/HEDguu/Tb8tYU9FajItj60FJ/WiGk/JksJPzWsOCVPVniy9fTbTLy1e+dCpCI6OXirtm7hvbodRNDjree0wSEzm7vL0wVzEZFo6kX+ABGUwaoO7pPyH+hgyI5Iuhc65NHsHzTJpf8yNFl9QGhkxvm2Ff2oEtDt1idOTBrHB6tg+ti9Ctb2+2yzBnk14hsSYJnKitR7wM6ZCFPX4eYQKBgQD+JAREeFkodec/SC+GX+4Q4Y68uMPkfUPrMKXM4cyY5wgXk64RBvRVxIxX7x6Y3tIKn9v8tWAprbsyVr15eb4RcAFEVwjuoZixhd9sIPsRhfdNolKn/fSPIsHL4ywcJMSIt7KVKHuQeqBNHy0o0PxQjNej1ozsmrAWqV55cbKHswKBgQDI2JQRTPIEC/2y6LdmBVhGJW9OKWTYdVNjq7rX+Yw4uxOtfd5hBqpvgZEklKEk72aazFdEcERlAm9SqoX09qk6zK/wcq4Xn5Q/qy8ecmjuyf2AK9X+HUdMerMVxhK9RpeevKYP/RO2F/wIN64anlQVYygVkXXgdOvWhBE4YABKgwKBgDRtmbPGYB5ItHwJmERQZfx1i8zDESaB8RED6DBsJJkmkDTM8ovws1c+RPWfDuDalto6QFfR0xTGEmhAHLaCtwNB6AEBM4aHL8jvpTfZVfI3gN0zL3oYmestcG1vYBouO504yE6dG2Ci6479b4OMGYFEjPfvuwLUpp8GMcc7/WihAoGANCp8mtm/ammq5VMof2kX+nAyrrx1ovsmQ5cRGpOIZhvBCqjMn6rZjci7aCLqj+tWXRKCABagzROK0o/T50JBxjHv6KYArcYW/Up7HI9ezdbM7wNzu2LjZ+veo+MkbuDs9J/PCgwTmJI2NfQwVl2VPVDZ0nBLi5cSwk7fIiNdL/0CgYEAtECmC1QDs53Di2MIsa/Fe4sWfJGSDqEWqhcA/aPwf1skM6VJJXBBMV1qFtwgO1AlLnu9dQYra6ylsUoubVYIXM9XK7EMhbqi57+Q75jHFTc0DnzOTyho5Gp4Ddi8dztmZGNWdWTGdeMqh+svqMXkD6VdJeddyGu/Zlgj7Wk6whU="; } public static String getChargeWebhooksData() { diff --git a/src/test/java/com/pingplusplus/RequestOptionsTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/RequestOptionsTest.java similarity index 100% rename from src/test/java/com/pingplusplus/RequestOptionsTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/RequestOptionsTest.java diff --git a/src/test/java/com/pingplusplus/SubBankTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/SubBankTest.java similarity index 100% rename from src/test/java/com/pingplusplus/SubBankTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/SubBankTest.java diff --git a/src/test/java/com/pingplusplus/WebhookTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/WebhookTest.java similarity index 100% rename from src/test/java/com/pingplusplus/WebhookTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/WebhookTest.java diff --git a/src/test/java/com/pingplusplus/WeixinOpenidTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/WeixinOpenidTest.java similarity index 100% rename from src/test/java/com/pingplusplus/WeixinOpenidTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/WeixinOpenidTest.java diff --git a/src/test/java/com/pingplusplus/agreement/AgreenmentTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/agreement/AgreenmentTest.java similarity index 100% rename from src/test/java/com/pingplusplus/agreement/AgreenmentTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/agreement/AgreenmentTest.java diff --git a/src/test/java/com/pingplusplus/balance/BalanceBonusTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceBonusTest.java similarity index 100% rename from src/test/java/com/pingplusplus/balance/BalanceBonusTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceBonusTest.java diff --git a/src/test/java/com/pingplusplus/balance/BalanceSettlementTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceSettlementTest.java similarity index 100% rename from src/test/java/com/pingplusplus/balance/BalanceSettlementTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceSettlementTest.java diff --git a/src/test/java/com/pingplusplus/balance/BalanceTransactionTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceTransactionTest.java similarity index 100% rename from src/test/java/com/pingplusplus/balance/BalanceTransactionTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceTransactionTest.java diff --git a/src/test/java/com/pingplusplus/balance/BalanceTransferTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceTransferTest.java similarity index 100% rename from src/test/java/com/pingplusplus/balance/BalanceTransferTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/balance/BalanceTransferTest.java diff --git a/src/test/java/com/pingplusplus/coupon/CouponTemplateTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/coupon/CouponTemplateTest.java similarity index 100% rename from src/test/java/com/pingplusplus/coupon/CouponTemplateTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/coupon/CouponTemplateTest.java diff --git a/src/test/java/com/pingplusplus/coupon/CouponTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/coupon/CouponTest.java similarity index 100% rename from src/test/java/com/pingplusplus/coupon/CouponTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/coupon/CouponTest.java diff --git a/src/test/java/com/pingplusplus/order/OrderTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/order/OrderTest.java similarity index 100% rename from src/test/java/com/pingplusplus/order/OrderTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/order/OrderTest.java diff --git a/src/test/java/com/pingplusplus/order/RoyaltySettlementTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltySettlementTest.java similarity index 100% rename from src/test/java/com/pingplusplus/order/RoyaltySettlementTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltySettlementTest.java diff --git a/src/test/java/com/pingplusplus/order/RoyaltyTemplateTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTemplateTest.java similarity index 100% rename from src/test/java/com/pingplusplus/order/RoyaltyTemplateTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTemplateTest.java diff --git a/src/test/java/com/pingplusplus/order/RoyaltyTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTest.java similarity index 100% rename from src/test/java/com/pingplusplus/order/RoyaltyTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTest.java diff --git a/src/test/java/com/pingplusplus/order/RoyaltyTransactionTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTransactionTest.java similarity index 100% rename from src/test/java/com/pingplusplus/order/RoyaltyTransactionTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/order/RoyaltyTransactionTest.java diff --git a/src/test/java/com/pingplusplus/recharge/RechargeTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/recharge/RechargeTest.java similarity index 100% rename from src/test/java/com/pingplusplus/recharge/RechargeTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/recharge/RechargeTest.java diff --git a/src/test/java/com/pingplusplus/settle_account/SettleAccountTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/settle_account/SettleAccountTest.java similarity index 100% rename from src/test/java/com/pingplusplus/settle_account/SettleAccountTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/settle_account/SettleAccountTest.java diff --git a/src/test/java/com/pingplusplus/split/ProfitTransactionTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/split/ProfitTransactionTest.java similarity index 100% rename from src/test/java/com/pingplusplus/split/ProfitTransactionTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/split/ProfitTransactionTest.java diff --git a/src/test/java/com/pingplusplus/split/SplitProfitTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/split/SplitProfitTest.java similarity index 100% rename from src/test/java/com/pingplusplus/split/SplitProfitTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/split/SplitProfitTest.java diff --git a/src/test/java/com/pingplusplus/split/SplitReceiverTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/split/SplitReceiverTest.java similarity index 100% rename from src/test/java/com/pingplusplus/split/SplitReceiverTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/split/SplitReceiverTest.java diff --git a/src/test/java/com/pingplusplus/sub_app/ContactTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/sub_app/ContactTest.java similarity index 100% rename from src/test/java/com/pingplusplus/sub_app/ContactTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/sub_app/ContactTest.java diff --git a/src/test/java/com/pingplusplus/sub_app/SubAppChannelTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/sub_app/SubAppChannelTest.java similarity index 100% rename from src/test/java/com/pingplusplus/sub_app/SubAppChannelTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/sub_app/SubAppChannelTest.java diff --git a/src/test/java/com/pingplusplus/sub_app/SubAppTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/sub_app/SubAppTest.java similarity index 100% rename from src/test/java/com/pingplusplus/sub_app/SubAppTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/sub_app/SubAppTest.java diff --git a/src/test/java/com/pingplusplus/transfer/TransferTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/transfer/TransferTest.java similarity index 100% rename from src/test/java/com/pingplusplus/transfer/TransferTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/transfer/TransferTest.java diff --git a/src/test/java/com/pingplusplus/user/UserPicTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/user/UserPicTest.java similarity index 100% rename from src/test/java/com/pingplusplus/user/UserPicTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/user/UserPicTest.java diff --git a/src/test/java/com/pingplusplus/user/UserTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/user/UserTest.java similarity index 100% rename from src/test/java/com/pingplusplus/user/UserTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/user/UserTest.java diff --git a/src/test/java/com/pingplusplus/withdrawal/BatchWithdrawalTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/withdrawal/BatchWithdrawalTest.java similarity index 100% rename from src/test/java/com/pingplusplus/withdrawal/BatchWithdrawalTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/withdrawal/BatchWithdrawalTest.java diff --git a/src/test/java/com/pingplusplus/withdrawal/WithdrawalTest.java b/pingpp-sdk/src/test/java/com/pingplusplus/withdrawal/WithdrawalTest.java similarity index 100% rename from src/test/java/com/pingplusplus/withdrawal/WithdrawalTest.java rename to pingpp-sdk/src/test/java/com/pingplusplus/withdrawal/WithdrawalTest.java diff --git a/pom.xml b/pom.xml index 908d423..71f3e19 100644 --- a/pom.xml +++ b/pom.xml @@ -1,23 +1,63 @@ - + 4.0.0 - Pingplusplus - pingpp-java - 2.4.1 + + com.pingxx + pingpp-java-parent + 2.5.6 + pom + + A Java SDK for Ping++ Payment API. + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + + scm:git:https://github.com/PingPlusPlus/pingpp-java.git + + + + afon + Afon + xufeng.weng@pingxx.com + + + + + pingpp-sdk + + + + 1.8 + 1.8 + + - - com.google.code.gson - gson - 2.8.9 - runtime - - - commons-codec - commons-codec - 1.10 - runtime - - pingpp-java - https://github.com/PingPlusPlus/pingpp-java + + + + + org.apache.maven.plugins + maven-install-plugin + 2.5.2 + + true + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + + + diff --git a/settings.gradle b/settings.gradle index 05ca5f7..c5a152d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ rootProject.name = 'pingpp-java' +include 'pingpp-sdk' include 'example' diff --git a/src/main/java/com/pingplusplus/util/PingppSignature.java b/src/main/java/com/pingplusplus/util/PingppSignature.java deleted file mode 100644 index e234427..0000000 --- a/src/main/java/com/pingplusplus/util/PingppSignature.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.pingplusplus.util; - -import com.pingplusplus.Pingpp; -import org.apache.commons.codec.binary.Base64; - -import java.io.UnsupportedEncodingException; -import java.security.*; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; - -/** - * Created by Afon on 2016/12/16. - */ -public class PingppSignature { - public static String sign(String data, String PEMEncodedPrivateKey, String charset) { - PrivateKey privateKey = getPrivateKeyFromPEM(PEMEncodedPrivateKey); - if (privateKey == null) { - return null; - } - - try { - Signature signature = Signature.getInstance("SHA256withRSA"); - signature.initSign(privateKey); - signature.update(data.getBytes(charset)); - byte[] signBytes = signature.sign(); - - return Base64.encodeBase64String(signBytes).replaceAll("[\n\r]", ""); - } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | UnsupportedEncodingException e) { - e.printStackTrace(); - } - - return null; - } - - public static PrivateKey getPrivateKeyFromPEM(String PEMEncodedPrivateKey) { - PEMEncodedPrivateKey = PEMEncodedPrivateKey - .replaceAll("(-+BEGIN (RSA )?PRIVATE KEY-+\\r?\\n|-+END (RSA )?PRIVATE KEY-+\\r?\\n?)", ""); - byte[] privateKeyBytes = Base64.decodeBase64(PEMEncodedPrivateKey); - - try { - return generatePrivateKeyWithPKCS8(privateKeyBytes); - } catch (InvalidKeySpecException e) { - if (Pingpp.DEBUG) { - e.printStackTrace(); - } - return null; - } - } - - public static PrivateKey generatePrivateKeyWithPKCS8(byte[] privateKeyBytes) - throws InvalidKeySpecException { - try { - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); - KeyFactory kf = KeyFactory.getInstance("RSA"); - return kf.generatePrivate(keySpec); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } - return null; - } -}