コミットを比較

...

49 コミット

作成者 SHA1 メッセージ 日付
  xhxu 8f9f1a1cf2 //wxscheme 1年前
  xhxu 6299762a76 //log 2年前
  xhxu 1a6643cd5a //log 2年前
  xhxu e9b9fb33ff //log 2年前
  xhxu 4687a8e54c //会员卡 商圈相关——1 2年前
  zhengfangyuan 49f54f239e Merge branch 'formao-live' of https://git.malls.iformall.com/server/wxJava-final into formao-live 2年前
  zhengfangyuan 5e9242ea8f fix pay v3 2年前
  xhxu 4d49ffa35a Merge remote-tracking branch 'origin/formao-live' into formao-live 2年前
  xhxu 3c001cbb09 // test 2年前
  zhengfangyuan 4d1021d026 fix log 2年前
  zhengfangyuan 454a851bab fix bug 2年前
  zhengfangyuan 32a868fc43 add log 2年前
  zhengfangyuan e3ddc82a26 add log 2年前
  zhengfangyuan 2b66930cbf fix pay v3 2年前
  xhxu 232425a094 // add bank shar 2年前
  xhxu 7db21daa4b // add shar app 2年前
  xhxu 06d0d8f8ac // add shar 2年前
  xhxu 2ee4a96ab5 // add api 2年前
  xhxu 51aa930547 // add api 2年前
  zhengfangyuan 50c93fa40b fix v3 pay 2年前
  zhengfangyuan 4b255c3cb3 fix v3 bug 2年前
  zhengfangyuan e56b4b52f3 fix 2年前
  zhengfangyuan 376d493b80 add log 2年前
  xhxu 678166a7fe //tt coupon order 2年前
  xhxu 1c43527d4a //tt log 2年前
  xhxu b8ae64b4f9 //tt log 2年前
  xhxu 0e8887a176 //tt log 2年前
  xhxu a2f35198f7 //tt pay v2 3年前
  xhxu 5aebf46bb7 //ttpayv2 3年前
  xhxu cd0f61acab //update test 3年前
  xhxu 0601ec89f6 //add ttweb 3年前
  xhxu e38443e08d /、qrcode 3年前
  xhxu 94b1cc1658 /、qrcode 3年前
  xhxu 27642b8878 update 3年前
  xhxu 7fda673d11 jiemi 会员 3年前
  xhxu 1249ecf317 ceshi jiemi 会员 3年前
  xhxu d1ca9fb57d ceshi jiemi会员 3年前
  xhxu ae2990d0f9 还原 3年前
  xhxu 43abd63272 3年前
  xhxu 11b43728cc wxbusiness 4年前
  xhxu dd3240f8de update weixin pay 4年前
  xiaohanzi bea32490b5 Merge branch 'formao-live' of https://git.youlane.cn/server/wxJava-final into formao-live 4年前
  xiaohanzi fc2098c6d9 更改直播接口地址 4年前
  xhxu ff1d40d438 WxMaLiveService.java 4年前
  xiaohanzi be1e361cd1 添加微信日志信息 5年前
  xiaohanzi de0e9c4dc5 添加微信调用url日志信息 5年前
  Burce 1e8e731d93 增加小程序直播类相关接口 5年前
  yjwang 976e9aaf89 🐛 #1512 修复小程序直播官方文档live_satus字段拼错问题,调整为live_status 5年前
  yjwang d744cd5dd8 🆕 #1429 增加小程序直播类相关接口 5年前
100個のファイルの変更5718行の追加83行の削除
分割表示
  1. +3
    -4
      pom.xml
  2. +1
    -1
      spring-boot-starters/pom.xml
  3. +1
    -1
      spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
  4. +1
    -1
      spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
  5. +1
    -1
      spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
  6. +1
    -1
      spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
  7. +8
    -0
      spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java
  8. +30
    -0
      spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java
  9. +1
    -1
      weixin-graal/pom.xml
  10. +1
    -1
      weixin-java-common/pom.xml
  11. +6
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  12. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java
  13. +23
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxRuntimeException.java
  14. +11
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java
  15. +3
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java
  16. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java
  17. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java
  18. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java
  19. +26
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonParser.java
  20. +9
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java
  21. +1
    -1
      weixin-java-cp/pom.xml
  22. +2
    -2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java
  23. +1
    -1
      weixin-java-miniapp/pom.xml
  24. +62
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaLiveService.java
  25. +36
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSchemeService.java
  26. +14
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
  27. +100
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaLiveServiceImpl.java
  28. +56
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSchemeServiceImpl.java
  29. +12
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java
  30. +88
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaGetLiveInfo.java
  31. +1
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaPhoneNumberInfo.java
  32. +75
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/scheme/WxMaGenerateNfcSchemeRequest.java
  33. +94
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/scheme/WxMaGenerateSchemeRequest.java
  34. +55
    -0
      weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaLiveServiceImplTest.java
  35. +1
    -1
      weixin-java-mp/pom.xml
  36. +1
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java
  37. +2
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteJoddHttpRequestExecutor.java
  38. +2
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoJoddHttpRequestExecutor.java
  39. +2
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadJoddHttpRequestExecutor.java
  40. +2
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoJoddHttpRequestExecutor.java
  41. +1
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadJoddHttpRequestExecutor.java
  42. +2
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadHttpRequestExecutor.java
  43. +3
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeJoddHttpRequestExecutor.java
  44. +1
    -1
      weixin-java-open/pom.xml
  45. +2
    -0
      weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
  46. +29
    -0
      weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java
  47. +3
    -3
      weixin-java-open/src/main/java/me/chanjar/weixin/open/executor/MaQrCodeJoddHttpRequestExecutor.java
  48. +13
    -1
      weixin-java-pay/pom.xml
  49. +87
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/ApplymentStateQueryResult.java
  50. +62
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/ModifySettlementRequest.java
  51. +62
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/SettlementInfoResult.java
  52. +1196
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/WxPayApplyment4SubCreateRequest.java
  53. +31
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/WxPayApplymentCreateResult.java
  54. +18
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/AccountTypeEnum.java
  55. +42
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/ApplymentStateEnum.java
  56. +18
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/BankAccountTypeEnum.java
  57. +64
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/CertTypeEnum.java
  58. +17
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/ContactTypeEnum.java
  59. +20
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/IdHolderEnum.java
  60. +41
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/IdTypeEnum.java
  61. +20
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/MicroBizTypeEnum.java
  62. +32
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SalesScenesTypeEnum.java
  63. +23
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SettlementVerifyResultEnum.java
  64. +34
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SubjectTypeEnum.java
  65. +28
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankAccountResult.java
  66. +176
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankBranchesResult.java
  67. +39
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankInfo.java
  68. +64
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankingResult.java
  69. +80
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/CitiesResult.java
  70. +59
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/PageLink.java
  71. +81
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/ProvincesResult.java
  72. +93
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/BusinessCircleNotifyData.java
  73. +52
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeNotifyResult.java
  74. +53
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeResult.java
  75. +112
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PaidResult.java
  76. +103
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/ParkingNotifyRequest.java
  77. +31
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsCommitStatusResult.java
  78. +154
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsNotifyRequest.java
  79. +121
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/RefundResult.java
  80. +35
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/SignatureHeader.java
  81. +28
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/ImageUploadResult.java
  82. +29
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java
  83. +82
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardActivateResult.java
  84. +93
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardNotifyData.java
  85. +360
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardResult.java
  86. +104
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardRightsRequest.java
  87. +95
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardUpdRequest.java
  88. +178
    -34
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java
  89. +74
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/Applyment4SubService.java
  90. +121
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BankService.java
  91. +59
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BusinessCircleService.java
  92. +50
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MemberCardService.java
  93. +46
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MerchantMediaService.java
  94. +120
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java
  95. +66
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/Applyment4SubServiceImpl.java
  96. +68
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BankServiceImpl.java
  97. +31
    -4
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
  98. +125
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BusinessCircleServiceImpl.java
  99. +87
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MemberCardServiceImpl.java
  100. +60
    -0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MerchantMediaServiceImpl.java

+ 3
- 4
pom.xml ファイルの表示

@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
<packaging>pom</packaging>
<name>WxJava - Weixin/Wechat Java SDK</name>
<description>微信开发Java SDK</description>
@@ -126,11 +126,10 @@
<artifactId>qrcode-utils</artifactId>
<version>1.1</version>
</dependency>
<!-- 由于jodd-http较新的3.8版本需要jdk8,故而此处采用较低版本 -->
<dependency>
<groupId>org.jodd</groupId>
<artifactId>jodd-http</artifactId>
<version>3.7.1</version>
<version>5.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -163,7 +162,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
<version>3.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>


+ 1
- 1
spring-boot-starters/pom.xml ファイルの表示

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<packaging>pom</packaging>
<artifactId>wx-java-spring-boot-starters</artifactId>


+ 1
- 1
spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml ファイルの表示

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>



+ 1
- 1
spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml ファイルの表示

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>



+ 1
- 1
spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml ファイルの表示

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>



+ 1
- 1
spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml ファイルの表示

@@ -5,7 +5,7 @@
<parent>
<artifactId>wx-java-spring-boot-starters</artifactId>
<groupId>com.github.binarywang</groupId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>



+ 8
- 0
spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java ファイルの表示

@@ -50,6 +50,14 @@ public class WxPayAutoConfiguration {
payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));

//以下是apiv3以及支付分相关
payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId()));
payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl()));
payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));
payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key()));

wxPayService.setConfig(payConfig);
return wxPayService;
}


+ 30
- 0
spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java ファイルの表示

@@ -43,4 +43,34 @@ public class WxPayProperties {
* apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定.
*/
private String keyPath;

/**
* 微信支付分serviceId
*/
private String serviceId;

/**
* 证书序列号
*/
private String certSerialNo;

/**
* apiV3秘钥
*/
private String apiv3Key;

/**
* 微信支付分回调地址
*/
private String payScoreNotifyUrl;

/**
* apiv3 商户apiclient_key.pem
*/
private String privateKeyPath;

/**
* apiv3 商户apiclient_cert.pem
*/
private String privateCertPath;
}

+ 1
- 1
weixin-graal/pom.xml ファイルの表示

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-graal</artifactId>


+ 1
- 1
weixin-java-common/pom.xml ファイルの表示

@@ -6,7 +6,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-java-common</artifactId>


+ 6
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java ファイルの表示

@@ -9,6 +9,12 @@ import java.util.Map;
* @author Daniel Qian & binarywang
*/
public class WxConsts {

/**
* 微信接口返回的参数errcode.
*/
public static final String ERR_CODE = "errcode";

/**
* 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型.
*/


+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java ファイルの表示

@@ -88,7 +88,7 @@ public class WxError implements Serializable {
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg;
}

return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg + ",微信原始报文:" + this.json;
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg + ",原始报文:" + this.json;
}

}

+ 23
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxRuntimeException.java ファイルの表示

@@ -0,0 +1,23 @@
package me.chanjar.weixin.common.error;

/**
* WxJava专用的runtime exception.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* @date 2020-09-26
*/
public class WxRuntimeException extends RuntimeException {
private static final long serialVersionUID = 4881698471192264412L;

public WxRuntimeException(Throwable e) {
super(e);
}

public WxRuntimeException(String msg) {
super(msg);
}

public WxRuntimeException(String msg, Throwable e) {
super(msg, e);
}
}

+ 11
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientSimpleGetRequestExecutor.java ファイルの表示

@@ -1,15 +1,20 @@
package me.chanjar.weixin.common.util.http.apache;

import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.WxDnsResolver;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

@@ -20,6 +25,7 @@ import java.io.IOException;
* @date 2017/5/4
*/
public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestExecutor<CloseableHttpClient, HttpHost> {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
public ApacheHttpClientSimpleGetRequestExecutor(RequestHttp requestHttp) {
super(requestHttp);
}
@@ -39,6 +45,11 @@ public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestEx
}

try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet)) {
// Header[] allHeaders = response.getAllHeaders();
// for (Header header:allHeaders) {
// log.info("\n【header】:"+header.getName()+"="+header.getValue());
// }

String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
WxError error = WxError.fromJson(responseContent, wxType);
if (error.getErrorCode() != 0) {


+ 3
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -19,6 +18,8 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;


/**
* .
@@ -47,7 +48,7 @@ public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadReque
request.withConnectionProvider(requestHttp.getRequestHttpClient());

HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());

String contentType = response.header("Content-Type");
if (contentType != null && contentType.startsWith("application/json")) {


+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaUploadRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxError;
@@ -14,6 +13,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* .
@@ -35,7 +35,7 @@ public class JoddHttpMediaUploadRequestExecutor extends MediaUploadRequestExecut
request.withConnectionProvider(requestHttp.getRequestHttpClient());
request.form("media", file);
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());

String responseContent = response.bodyText();
WxError error = WxError.fromJson(responseContent, wxType);


+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimpleGetRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -12,6 +11,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* .
@@ -39,7 +39,7 @@ public class JoddHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<H
}
request.withConnectionProvider(requestHttp.getRequestHttpClient());
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());

String responseContent = response.bodyText();



+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -12,6 +11,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* .
@@ -38,7 +38,7 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor
request.bodyText(postEntity);
}
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());

String responseContent = response.bodyText();
if (responseContent.isEmpty()) {


+ 26
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonParser.java ファイルの表示

@@ -0,0 +1,26 @@
package me.chanjar.weixin.common.util.json;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;

import java.io.Reader;

/**
* @author niefy
*/
public class GsonParser {
private static final JsonParser JSON_PARSER = new JsonParser();

public static JsonObject parse(String json) {
return JSON_PARSER.parse(json).getAsJsonObject();
}

public static JsonObject parse(Reader json) {
return JSON_PARSER.parse(json).getAsJsonObject();
}

public static JsonObject parse(JsonReader json) {
return JSON_PARSER.parse(json).getAsJsonObject();
}
}

+ 9
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java ファイルの表示

@@ -18,9 +18,18 @@ public class WxErrorAdapter implements JsonDeserializer<WxError> {

if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) {
errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode")));
} else if(wxErrorJsonObject.get("err_no") != null && !wxErrorJsonObject.get("err_no").isJsonNull()) {
errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("err_no")));
} else if(wxErrorJsonObject.get("error_code") != null && !wxErrorJsonObject.get("error_code").isJsonNull()){
errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("error_code")));
}

if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) {
errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg")));
} else if (wxErrorJsonObject.get("err_tips") != null && !wxErrorJsonObject.get("err_tips").isJsonNull()) {
errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("err_tips")));
} else if (wxErrorJsonObject.get("description") != null && !wxErrorJsonObject.get("description").isJsonNull()) {
errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("description")));
}

errorBuilder.json(json.toString());


+ 1
- 1
weixin-java-cp/pom.xml ファイルの表示

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-java-cp</artifactId>


+ 2
- 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java ファイルの表示

@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.api.impl;
import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.JoddHttp;
import jodd.http.ProxyInfo;
import jodd.http.net.SocketHttpConnectionProvider;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.error.WxError;
@@ -68,7 +68,7 @@ public class WxCpServiceJoddHttpImpl extends BaseWxCpServiceImpl<HttpConnectionP
configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
}

httpClient = JoddHttp.httpConnectionProvider;
httpClient = new SocketHttpConnectionProvider();
}

@Override


+ 1
- 1
weixin-java-miniapp/pom.xml ファイルの表示

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-java-miniapp</artifactId>


+ 62
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaLiveService.java ファイルの表示

@@ -0,0 +1,62 @@
package cn.binarywang.wx.miniapp.api;

import cn.binarywang.wx.miniapp.bean.WxMaGetLiveInfo;
import me.chanjar.weixin.common.error.WxErrorException;

import java.util.List;

/**
* <pre>
* 直播相关操作接口.
* Created by yjwang on 2020/4/5.
* </pre>
*
* @author <a href="https://github.com/yjwang3300300">yjwang</a>
*/
public interface WxMaLiveService {
String GET_LIVE_INFO = "https://api.weixin.qq.com/wxa/business/getliveinfo";

/**
* 获取直播房间列表.(分页)
*
* @param start 起始拉取房间,start = 0 表示从第 1 个房间开始拉取
* @param limit 每次拉取的个数上限,不要设置过大,建议 100 以内
* @return .
* @throws WxErrorException .
*/
WxMaGetLiveInfo getLiveInfo(Integer start, Integer limit) throws WxErrorException;

/**
* 获取所有直播间信息(没有分页直接获取全部)
* @return
* @throws WxErrorException
*/
List<WxMaGetLiveInfo.RoomInfo> getLiveinfos() throws WxErrorException;

/**
*
* 获取直播房间回放数据信息.
*
* @param action 获取回放
* @param room_id 直播间 id
* @param start 起始拉取视频,start = 0 表示从第 1 个视频片段开始拉取
* @param limit 每次拉取的个数上限,不要设置过大,建议 100 以内
* @return
* @throws WxErrorException
*/
WxMaGetLiveInfo getLiveReplay(String action, Integer room_id, Integer start, Integer limit) throws WxErrorException;

/**
*
* 获取直播房间回放数据信息.
*
* 获取回放 (默认:get_replay)
* @param room_id 直播间 id
* @param start 起始拉取视频,start = 0 表示从第 1 个视频片段开始拉取
* @param limit 每次拉取的个数上限,不要设置过大,建议 100 以内
* @return
* @throws WxErrorException
*/
WxMaGetLiveInfo getLiveReplay(Integer room_id, Integer start, Integer limit) throws WxErrorException;

}

+ 36
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSchemeService.java ファイルの表示

@@ -0,0 +1,36 @@
package cn.binarywang.wx.miniapp.api;

import cn.binarywang.wx.miniapp.bean.scheme.WxMaGenerateNfcSchemeRequest;
import cn.binarywang.wx.miniapp.bean.scheme.WxMaGenerateSchemeRequest;
import me.chanjar.weixin.common.error.WxErrorException;

/**
* <pre>
* 小程序Scheme码相关操作接口.
*
*
* </pre>
*
* @author : cofedream
* created on : 2021-01-26
*/
public interface WxMaSchemeService {

String GENERATE_SCHEME_URL = "https://api.weixin.qq.com/wxa/generatescheme";
String GENERATE_NFC_SCHEME_URL = "https://api.weixin.qq.com/wxa/generatenfcscheme";

/**
* 获取小程序scheme码
*文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-scheme/urlscheme.generate.html
* @param request 请求参数
* @throws WxErrorException 生成失败时抛出,具体错误码请看文档
*/
String generate(WxMaGenerateSchemeRequest request) throws WxErrorException;
/**
* 获取NFC 的小程序 scheme
*文档地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateNFCScheme.html
* @param request 请求参数
* @throws WxErrorException 生成失败时抛出,具体错误码请看文档
*/
String generateNFC(WxMaGenerateNfcSchemeRequest request) throws WxErrorException;
}

+ 14
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java ファイルの表示

@@ -156,6 +156,13 @@ public interface WxMaService {
*/
WxMaQrcodeService getQrcodeService();

/**
* 返回获取小程序scheme码实现对象,以方便调用其各个接口.
*
* @return WxMaSchemeService wx ma scheme service
*/
WxMaSchemeService getWxMaSchemeService();

/**
* 返回模板配置相关接口方法的实现类对象, 以方便调用其各个接口.
*
@@ -247,4 +254,11 @@ public interface WxMaService {
* 获取云开发接口服务对象
*/
WxMaCloudService getCloudService();

/**
* 获取直播接口服务对象
*
* @return .
*/
WxMaLiveService getLiveService();
}

+ 100
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaLiveServiceImpl.java ファイルの表示

@@ -0,0 +1,100 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaLiveService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaGetLiveInfo;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* <pre>
* Created by yjwang on 2020/4/5.
* </pre>
*
* @author <a href="https://github.com/yjwang3300300">yjwang</a>
*/
@AllArgsConstructor
public class WxMaLiveServiceImpl implements WxMaLiveService {
private static final JsonParser JSON_PARSER = new JsonParser();
private WxMaService service;

@Override
public WxMaGetLiveInfo getLiveInfo(Integer start, Integer limit) throws WxErrorException {
JsonObject jsonObject = getJsonObject(start, limit, null);
return WxMaGetLiveInfo.fromJson(jsonObject.toString());
}

@Override
public List<WxMaGetLiveInfo.RoomInfo> getLiveinfos() throws WxErrorException {
List<WxMaGetLiveInfo.RoomInfo> results = new ArrayList<>();
Integer start = 0;
Integer limit = 80;
Integer tatal = 0;
WxMaGetLiveInfo liveInfo = null;
do {
if (tatal != 0 && tatal <= start) {
break;
}
liveInfo = getLiveInfo(start, limit);
if (liveInfo == null) {
return null;
}
results.addAll(liveInfo.getRoomInfos());
tatal = liveInfo.getTotal();
start = results.size();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (results.size() <= tatal);
return results;
}

@Override
public WxMaGetLiveInfo getLiveReplay(String action, Integer room_id, Integer start, Integer limit) throws WxErrorException {
Map<String, Object> map = new HashMap(4);
map.put("action", action);
map.put("room_id", room_id);
JsonObject jsonObject = getJsonObject(start, limit, map);
return WxMaGetLiveInfo.fromJson(jsonObject.toString());
}

@Override
public WxMaGetLiveInfo getLiveReplay(Integer room_id, Integer start, Integer limit) throws WxErrorException {
return getLiveReplay("get_replay", room_id, start, limit);
}

/**
* 包装一下
*
* @param start
* @param limit
* @param map
* @return
* @throws WxErrorException
*/
private JsonObject getJsonObject(Integer start, Integer limit, Map<String, Object> map) throws WxErrorException {
if (map == null) {
map = new HashMap(2);
}
map.put("start", start);
map.put("limit", limit);
String responseContent = service.post(GET_LIVE_INFO, WxMaGsonBuilder.create().toJson(map));
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (jsonObject.get("errcode").getAsInt() != 0) {
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
}
return jsonObject;
}
}

+ 56
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSchemeServiceImpl.java ファイルの表示

@@ -0,0 +1,56 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaSchemeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.scheme.WxMaGenerateNfcSchemeRequest;
import cn.binarywang.wx.miniapp.bean.scheme.WxMaGenerateSchemeRequest;
import com.google.gson.JsonObject;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonParser;

/**
* @author : cofedream
* created on : 2021-01-28
*/
@AllArgsConstructor
public class WxMaSchemeServiceImpl implements WxMaSchemeService {
private final WxMaService wxMaService;

/**
* 获取小程序scheme码
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/url-scheme/urlscheme.generate.html
*
* @param request 请求参数
* @throws WxErrorException 生成失败时抛出,具体错误码请看文档
*/
@Override
public String generate(WxMaGenerateSchemeRequest request) throws WxErrorException {
String responseContent = this.wxMaService.post(GENERATE_SCHEME_URL, request.toJson());
JsonObject jsonObject = GsonParser.parse(responseContent);
if (jsonObject.get(WxConsts.ERR_CODE).getAsInt() != 0) {
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
}
return jsonObject.get("openlink").getAsString();
}

/**
* 获取NFC 的小程序 scheme
* 文档地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateNFCScheme.html
*
* @param request 请求参数
* @throws WxErrorException 生成失败时抛出,具体错误码请看文档
*/
@Override
public String generateNFC(WxMaGenerateNfcSchemeRequest request) throws WxErrorException {
String responseContent = this.wxMaService.post(GENERATE_NFC_SCHEME_URL, request.toJson());
JsonObject jsonObject = GsonParser.parse(responseContent);
if (jsonObject.get(WxConsts.ERR_CODE).getAsInt() != 0) {
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
}
return jsonObject.get("openlink").getAsString();
}
}

+ 12
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java ファイルの表示

@@ -46,6 +46,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
private WxMaMediaService materialService = new WxMaMediaServiceImpl(this);
private WxMaUserService userService = new WxMaUserServiceImpl(this);
private WxMaQrcodeService qrCodeService = new WxMaQrcodeServiceImpl(this);
private WxMaSchemeService schemeService = new WxMaSchemeServiceImpl(this);
private WxMaTemplateService templateService = new WxMaTemplateServiceImpl(this);
private WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this);
private WxMaCodeService codeService = new WxMaCodeServiceImpl(this);
@@ -58,6 +59,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
private WxMaExpressService expressService = new WxMaExpressServiceImpl(this);
private WxMaSubscribeService subscribeService = new WxMaSubscribeServiceImpl(this);
private WxMaCloudService cloudService = new WxMaCloudServiceImpl(this);
private WxMaLiveService liveService = new WxMaLiveServiceImpl(this);

private int retrySleepMillis = 1000;
private int maxRetryTimes = 5;
@@ -330,6 +332,11 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
return this.qrCodeService;
}

@Override
public WxMaSchemeService getWxMaSchemeService() {
return schemeService;
}

@Override
public WxMaTemplateService getTemplateService() {
return this.templateService;
@@ -389,4 +396,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
public WxMaCloudService getCloudService() {
return this.cloudService;
}

@Override
public WxMaLiveService getLiveService() {
return this.liveService;
}
}

+ 88
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaGetLiveInfo.java ファイルの表示

@@ -0,0 +1,88 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
* 获取直播房间列表
*
* @author yjwang
* @date 2020/4/5
*/
@Data
public class WxMaGetLiveInfo implements Serializable {
private static final long serialVersionUID = 7285263767524755887L;
private Integer errcode;
private String errmsg;
private Integer total;
/**
* 直播间列表
*/
@SerializedName("room_info")
private List<RoomInfo> roomInfos;
/**
* 获取回放源视频列表
*/
@SerializedName("live_replay")
private List<LiveReplay> liveReplay;

public static WxMaGetLiveInfo fromJson(String json) {
return WxMaGsonBuilder.create().fromJson(json, WxMaGetLiveInfo.class);
}

/**
* 直播列表
*/
@Data
public static class RoomInfo implements Serializable {
private static final long serialVersionUID = 7745775280267417154L;
private String name;
private Integer roomid;
@SerializedName("cover_img")
private String coverImg;
@SerializedName("live_status")
private Integer liveStatus;
@SerializedName("start_time")
private Long startTime;
@SerializedName("end_time")
private Long endTime;
@SerializedName("anchor_name")
private String anchorName;
@SerializedName("anchor_img")
private String anchorImg;
private List<Goods> goods;
}

/**
* 商品列表
*/
@Data
public static class Goods implements Serializable {
private static final long serialVersionUID = 5769245932149287574L;
@SerializedName("cover_img")
private String coverImg;
private String url;
private String price;
private String name;
}

/**
* 回放数据列表
*/
@Data
public static class LiveReplay implements Serializable {
private static final long serialVersionUID = 7683927205627536320L;
@SerializedName("expire_time")
private String expireTime;
@SerializedName("create_time")
private String createTime;
@SerializedName("media_url")
private String mediaUrl;
}


}

+ 1
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaPhoneNumberInfo.java ファイルの表示

@@ -4,6 +4,7 @@ import java.io.Serializable;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
* 微信用户绑定的手机号相关信息


+ 75
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/scheme/WxMaGenerateNfcSchemeRequest.java ファイルの表示

@@ -0,0 +1,75 @@
package cn.binarywang.wx.miniapp.bean.scheme;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Data;

/**
* @author : lyt
* created on : 2023-07-31
*/
@Data
@Builder(builderMethodName = "newBuilder")
public class WxMaGenerateNfcSchemeRequest {
/**
* 跳转到的目标小程序信息。
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("jump_wxa")
private JumpWxa jumpWxa;

/**
* scheme对应的设备model_id
* <pre>
* 是否必填:是
* </pre>
*/
@SerializedName("model_id")
private String modelId;

/**
* scheme对应的设备sn,仅一机一码时填写
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("sn")
private String sn;

@Data
@Builder(builderMethodName = "newBuilder")
public static class JumpWxa {
/**
* 通过scheme码进入的小程序页面路径,必须是已经发布的小程序存在的页面,不可携带query。path为空时会跳转小程序主页。
* <pre>
* 是否必填:是
* </pre>
*/
@SerializedName("path")
private String path;

/**
* 通过scheme码进入小程序时的query,最大128个字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~
* 返回值
* <pre>
* 是否必填:是
* </pre>
*/
@SerializedName("query")
private String query;

/**
* 要打开的小程序版本。正式版为"release",体验版为"trial",开发版为"develop"默认值:release
*/
@SerializedName("env_version")
private String envVersion = "release";
}

public String toJson() {
return WxMaGsonBuilder.create().toJson(this);
}

}

+ 94
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/scheme/WxMaGenerateSchemeRequest.java ファイルの表示

@@ -0,0 +1,94 @@
package cn.binarywang.wx.miniapp.bean.scheme;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Builder;
import lombok.Data;

/**
* @author : cofedream
* created on : 2021-01-26
*/
@Data
@Builder(builderMethodName = "newBuilder")
public class WxMaGenerateSchemeRequest {
/**
* 跳转到的目标小程序信息。
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("jump_wxa")
private JumpWxa jumpWxa;

/**
* 生成的scheme码类型,到期失效:true,永久有效:false。
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("is_expire")
private Boolean isExpire;

/**
* 到期失效的scheme码的失效时间,为Unix时间戳。生成的到期失效scheme码在该时间前有效。最长有效期为1年。生成到期失效的scheme时必填。
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("expire_time")
private Long expireTime;

/**
* 到期失效的 scheme 码失效类型,失效时间:0,失效间隔天数:1
* <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("expire_type")
private Integer expireType;

/**
* 到期失效的 scheme 码的失效间隔天数。
* <pre>
* 生成的到期失效 scheme 码在该间隔时间到达前有效。最长间隔天数为365天。is_expire 为 true 且 expire_type 为 1 时必填 * <pre>
* 是否必填:否
* </pre>
*/
@SerializedName("expire_interval")
private Integer expireInterval;

@Data
@Builder(builderMethodName = "newBuilder")
public static class JumpWxa {
/**
* 通过scheme码进入的小程序页面路径,必须是已经发布的小程序存在的页面,不可携带query。path为空时会跳转小程序主页。
* <pre>
* 是否必填:是
* </pre>
*/
@SerializedName("path")
private String path;

/**
* 通过scheme码进入小程序时的query,最大128个字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~
* 返回值
* <pre>
* 是否必填:是
* </pre>
*/
@SerializedName("query")
private String query;

/**
* 要打开的小程序版本。正式版为"release",体验版为"trial",开发版为"develop"默认值:release
*/
@SerializedName("env_version")
private String envVersion = "release";
}

public String toJson() {
return WxMaGsonBuilder.create().toJson(this);
}

}

+ 55
- 0
weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaLiveServiceImplTest.java ファイルの表示

@@ -0,0 +1,55 @@
package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaGetLiveInfo;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.test.ApiTestModule;
import cn.binarywang.wx.miniapp.test.TestConfig;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonObject;
import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import java.util.List;
import java.util.stream.Collectors;

import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;

/**
* 测试直播相关的接口
*
* @author <a href="https://github.com/yjwang3300300">yjwang</a>
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaLiveServiceImplTest {

@Inject
private WxMaService wxService;

@Test
public void getLiveInfo() throws Exception {
WxMaGetLiveInfo list = this.wxService.getLiveService().getLiveInfo(0,10);
assertNotNull(list);
System.out.println(list.toString());
}

@Test
public void getLiveReplay() throws Exception {
// [12, 11, 10, 9, 8, 7, 6, 5, 3, 2]
WxMaGetLiveInfo list = this.wxService.getLiveService().getLiveReplay(11,0,10);
assertNotNull(list);
System.out.println(list.toString());
}

@Test
public void getLiveinfos() throws Exception {
List<WxMaGetLiveInfo.RoomInfo> list = this.wxService.getLiveService().getLiveinfos();
assertNotNull(list);
System.out.println(list.toString());
}
}

+ 1
- 1
weixin-java-mp/pom.xml ファイルの表示

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-java-mp</artifactId>


+ 1
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java ファイルの表示

@@ -46,7 +46,7 @@ public class WxMpServiceJoddHttpImpl extends BaseWxMpServiceImpl<HttpConnectionP
httpProxy = new ProxyInfo(ProxyInfo.ProxyType.HTTP, configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
}

httpClient = JoddHttp.httpConnectionProvider;
httpClient = new SocketHttpConnectionProvider();
}

@Override


+ 2
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialDeleteJoddHttpRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
@@ -12,6 +11,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* Created by ecoolper on 2017/5/5.
@@ -31,7 +31,7 @@ public class MaterialDeleteJoddHttpRequestExecutor extends MaterialDeleteRequest

request.query("media_id", materialId);
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String responseContent = response.bodyText();
WxError error = WxError.fromJson(responseContent, WxType.MP);
if (error.getErrorCode() != 0) {


+ 2
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialNewsInfoJoddHttpRequestExecutor.java ファイルの表示

@@ -5,7 +5,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
@@ -18,6 +17,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* Created by ecoolper on 2017/5/5.
@@ -38,7 +38,7 @@ public class MaterialNewsInfoJoddHttpRequestExecutor extends MaterialNewsInfoReq
.withConnectionProvider(requestHttp.getRequestHttpClient())
.body(WxGsonBuilder.create().toJson(ImmutableMap.of("media_id", materialId)));
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());

String responseContent = response.bodyText();
this.logger.debug("响应原始数据:{}", responseContent);


+ 2
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialUploadJoddHttpRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
@@ -17,6 +16,7 @@ import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
@@ -50,7 +50,7 @@ public class MaterialUploadJoddHttpRequestExecutor extends MaterialUploadRequest
}

HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String responseContent = response.bodyText();
WxError error = WxError.fromJson(responseContent, WxType.MP);
if (error.getErrorCode() != 0) {


+ 2
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVideoInfoJoddHttpRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
@@ -13,6 +12,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* Created by ecoolper on 2017/5/5.
@@ -32,7 +32,7 @@ public class MaterialVideoInfoJoddHttpRequestExecutor extends MaterialVideoInfoR

request.query("media_id", materialId);
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String responseContent = response.bodyText();
WxError error = WxError.fromJson(responseContent, WxType.MP);
if (error.getErrorCode() != 0) {


+ 1
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/material/MaterialVoiceAndImageDownloadJoddHttpRequestExecutor.java ファイルの表示

@@ -37,7 +37,7 @@ public class MaterialVoiceAndImageDownloadJoddHttpRequestExecutor extends Materi

request.query("media_id", materialId);
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) {
// 下载媒体文件出错
byte[] responseContent = IOUtils.toByteArray(inputStream);


+ 2
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/media/MediaImgUploadHttpRequestExecutor.java ファイルの表示

@@ -4,7 +4,6 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
@@ -14,6 +13,7 @@ import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
* Created by ecoolper on 2017/5/5.
@@ -39,7 +39,7 @@ public class MediaImgUploadHttpRequestExecutor extends MediaImgUploadRequestExec

request.form("media", data);
HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String responseContent = response.bodyText();
WxError error = WxError.fromJson(responseContent, WxType.MP);
if (error.getErrorCode() != 0) {


+ 3
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/requestexecuter/qrcode/QrCodeJoddHttpRequestExecutor.java ファイルの表示

@@ -4,9 +4,8 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.MimeTypes;
import jodd.util.StringPool;

import jodd.net.MimeTypes;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -19,6 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
@@ -47,7 +47,7 @@ public class QrCodeJoddHttpRequestExecutor extends QrCodeRequestExecutor<HttpCon
request.withConnectionProvider(requestHttp.getRequestHttpClient());

HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String contentTypeHeader = response.header("Content-Type");
if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) {
String responseContent = response.bodyText();


+ 1
- 1
weixin-java-open/pom.xml ファイルの表示

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>

<artifactId>weixin-java-open</artifactId>


+ 2
- 0
weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java ファイルの表示

@@ -166,6 +166,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
String componentAccessToken = getComponentAccessToken(false);
String uriWithComponentAccessToken = uri + (uri.contains("?") ? "&" : "?") + accessTokenKey + "=" + componentAccessToken;
try {
this.log.info("wxopencomponent excute url:"+uriWithComponentAccessToken);
return getWxOpenService().get(uriWithComponentAccessToken, null);
} catch (WxErrorException e) {
WxError error = e.getError();
@@ -246,6 +247,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {

@Override
public String route(final WxOpenXmlMessage wxMessage) throws WxErrorException {
log.info("wxopencomponent route :"+wxMessage);
if (wxMessage == null) {
throw new NullPointerException("message is empty");
}


+ 29
- 0
weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java ファイルの表示

@@ -8,6 +8,7 @@ import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage;
import me.chanjar.weixin.open.util.WxOpenCryptUtil;
import me.chanjar.weixin.open.util.xml.XStreamTransformer;
import org.apache.commons.io.IOUtils;
@@ -140,6 +141,7 @@ public class WxOpenXmlMessage implements Serializable {
String timestamp, String nonce, String msgSignature) {
WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage);
String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml);
log.debug("解密后的原始xml消息内容:{}", plainText);
return WxMpXmlMessage.fromXml(plainText);
}

@@ -152,4 +154,31 @@ public class WxOpenXmlMessage implements Serializable {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
WxOpenInMemoryConfigStorage wxOpenConfigStorage = new WxOpenInMemoryConfigStorage();
wxOpenConfigStorage.setComponentAesKey("");
wxOpenConfigStorage.setComponentToken("");
wxOpenConfigStorage.setComponentAppId("");

WxOpenCryptUtil cryptUtil = new WxOpenCryptUtil(wxOpenConfigStorage);
/**
* 接收微信APP回调:[appId=[wx3cb90ab25f132468], openid=[ok9Xtt7rErEqlQKBjaluwroxsHaM], signature=[50e3ddd2d2817cbc309ed0a4b9b6eafe6e4c8648], encType=[aes], msgSignature=[00c9b32600e67276a56e2092fe3dfe1c486318f5], timestamp=[1653534263], nonce=[897774971], requestBody=[
* <xml>
* <ToUserName><![CDATA[gh_ddfa54d85724]]></ToUserName>
* <Encrypt><![CDATA[EUzw+5L2Vsqs6fxq4ZGw1S/Hu/4Gx04Z4v2ZqE45OM5OHvK/6z0K21D2wdVv20YmswbsxW7bThe2vvoMqf8dktp4MbOqLMACpYt9B1UeQBoG0tnwiQo1PggTLr3iomBVxRERVpLcyIRZHbyGW0sg3zKjecVGlvMgL4fQFCZmi5swzuR8zXsHQ9LlPiB0jSaF37cj0g7YMyYlzZ1GRyleGljLER3P+Plqa727bpJjGwRgSkBBco8vm4bEcOyTiO0Yy5gARMHC2bcQkhqgUgp6XRyz5YM9jW6DwXPhVCY+X/vvTL1gPm/UAZpwY+YUNh+1o+xm45MX+FjHXN/kbdeVV6NqO8VGF0sP0XYBlenBm4a3CmxU5AjNTauM1f6KSpoLV0R1c02l2hbvpwZ32CEgD5uriOh2NWOnWuLD58AScA8xyIUzdENUsYlq60H9tRd4KRbSydcwp2ALCcm0B1KS/GDT/587TntnL+Ai2VrUSnlZej/ByV8D4dvEuAU+5/ky]]></Encrypt>
* </xml>
*
* ]
*/
String msgSignature = "50e3ddd2d2817cbc309ed0a4b9b6eafe6e4c8648";
String timestamp = "1653534263";
String nonce = "897774971";
String encryptedXml = "<xml>\n" +
" <ToUserName><![CDATA[gh_ddfa54d85724]]></ToUserName>\n" +
" <Encrypt><![CDATA[EUzw+5L2Vsqs6fxq4ZGw1S/Hu/4Gx04Z4v2ZqE45OM5OHvK/6z0K21D2wdVv20YmswbsxW7bThe2vvoMqf8dktp4MbOqLMACpYt9B1UeQBoG0tnwiQo1PggTLr3iomBVxRERVpLcyIRZHbyGW0sg3zKjecVGlvMgL4fQFCZmi5swzuR8zXsHQ9LlPiB0jSaF37cj0g7YMyYlzZ1GRyleGljLER3P+Plqa727bpJjGwRgSkBBco8vm4bEcOyTiO0Yy5gARMHC2bcQkhqgUgp6XRyz5YM9jW6DwXPhVCY+X/vvTL1gPm/UAZpwY+YUNh+1o+xm45MX+FjHXN/kbdeVV6NqO8VGF0sP0XYBlenBm4a3CmxU5AjNTauM1f6KSpoLV0R1c02l2hbvpwZ32CEgD5uriOh2NWOnWuLD58AScA8xyIUzdENUsYlq60H9tRd4KRbSydcwp2ALCcm0B1KS/GDT/587TntnL+Ai2VrUSnlZej/ByV8D4dvEuAU+5/ky]]></Encrypt>\n" +
"</xml>";
String plainText = cryptUtil.decrypt(msgSignature, timestamp, nonce, encryptedXml);
System.out.println(plainText);
}
}

+ 3
- 3
weixin-java-open/src/main/java/me/chanjar/weixin/open/executor/MaQrCodeJoddHttpRequestExecutor.java ファイルの表示

@@ -4,8 +4,7 @@ import jodd.http.HttpConnectionProvider;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.MimeTypes;
import jodd.util.StringPool;
import jodd.net.MimeTypes;
import me.chanjar.weixin.common.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -19,6 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

/**
@@ -49,7 +49,7 @@ public class MaQrCodeJoddHttpRequestExecutor extends MaQrCodeRequestExecutor<Htt
request.withConnectionProvider(requestHttp.getRequestHttpClient());

HttpResponse response = request.send();
response.charset(StringPool.UTF_8);
response.charset(StandardCharsets.UTF_8.name());
String contentTypeHeader = response.header("Content-Type");
if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) {
String responseContent = response.bodyText();


+ 13
- 1
weixin-java-pay/pom.xml ファイルの表示

@@ -5,13 +5,25 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java</artifactId>
<version>3.7.0</version>
<version>3.7.0.B</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>weixin-java-pay</artifactId>
<name>WxJava - PAY Java SDK</name>
<description>微信支付 Java SDK</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>


+ 87
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/ApplymentStateQueryResult.java ファイルの表示

@@ -0,0 +1,87 @@
package com.github.binarywang.wxpay.bean.applyment;

import com.github.binarywang.wxpay.bean.applyment.enums.ApplymentStateEnum;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.List;

/**
* 查询申请单状态返回对象信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ApplymentStateQueryResult implements Serializable {
private static final long serialVersionUID = 6539090917423486409L;
/**
* 业务申请编号
*/
@SerializedName("business_code")
private String businessCode;
/**
* 微信支付申请单号
*/
@SerializedName("applyment_id")
private String applymentId;
/**
* 特约商户号
*/
@SerializedName("sub_mchid")
private String subMchid;
/**
* 超级管理员签约链接
*/
@SerializedName("sign_url")
private String signUrl;

/**
* 申请单状态
*/
@SerializedName("applyment_state")
private ApplymentStateEnum applymentState;
/**
* 申请状态描述
*/
@SerializedName("applyment_state_msg")
private String applymentStateMsg;
/**
* 驳回原因详情
*/
@SerializedName("audit_detail")
private List<AuditDetail> auditDetail;

/**
* 驳回原因详情
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public static class AuditDetail {
/**
* 字段名
*/
@SerializedName("field")
private String field;
/**
* 字段名称
*/
@SerializedName("field_name")
private String fieldName;
/**
* 驳回原因
*/
@SerializedName("reject_reason")
private String rejectReason;

}
}

+ 62
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/ModifySettlementRequest.java ファイルの表示

@@ -0,0 +1,62 @@
package com.github.binarywang.wxpay.bean.applyment;

import com.github.binarywang.wxpay.bean.applyment.enums.AccountTypeEnum;
import com.github.binarywang.wxpay.v3.SpecEncrypt;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* 修改结算账户请求对象
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ModifySettlementRequest implements Serializable {
private static final long serialVersionUID = 4568552340365230872L;
/**
* 账户类型
*/
@SerializedName("account_type")
private AccountTypeEnum accountType;
/**
* 开户名称
*/
@SpecEncrypt
@SerializedName("account_name")
private String accountName;
/**
* 开户银行
*/
@SerializedName("account_bank")
private String accountBank;
/**
* 开户银行省市编码
*/
@SerializedName("bank_address_code")
private String bankAddressCode;
/**
* 开户银行全称(含支行)
*/
@SerializedName("bank_name")
private String bankName;
/**
* 开户银行联行号
*/
@SerializedName("bank_branch_id")
private String bankBranchId;

/**
* 银行账号
*/
@SpecEncrypt
@SerializedName("account_number")
private String accountNumber;
}

+ 62
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/SettlementInfoResult.java ファイルの表示

@@ -0,0 +1,62 @@
package com.github.binarywang.wxpay.bean.applyment;

import com.github.binarywang.wxpay.bean.applyment.enums.AccountTypeEnum;
import com.github.binarywang.wxpay.bean.applyment.enums.SettlementVerifyResultEnum;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
* 查询结算账户返回对象信息
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class SettlementInfoResult implements Serializable {
private static final long serialVersionUID = 4568552340365230872L;
/**
* 账户类型
*/
@SerializedName("account_type")
private AccountTypeEnum accountType;
/**
* 开户银行
*/
@SerializedName("account_bank")
private String accountBank;
/**
* 开户银行全称(含支行]
*/
@SerializedName("bank_name")
private String bankName;
/**
* 开户银行联行号
*/
@SerializedName("bank_branch_id")
private String bankBranchId;
/**
* 银行账号
*/
@SerializedName("account_number")
private String accountNumber;
/**
* 汇款验证结果
*
* @see com.github.binarywang.wxpay.bean.applyment.enums.SettlementVerifyResultEnum
*/
@SerializedName("verify_result")
private SettlementVerifyResultEnum verifyResult;

/**
* 汇款验证失败原因
*/
@SerializedName("verify_fail_reason")
private String verifyFailReason;
}

+ 1196
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/WxPayApplyment4SubCreateRequest.java
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 31
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/WxPayApplymentCreateResult.java ファイルの表示

@@ -0,0 +1,31 @@
package com.github.binarywang.wxpay.bean.applyment;

import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;


/**
* 特约商户进件 提交申请结果响应
*
* @author zhouyongshen
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class WxPayApplymentCreateResult implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 微信支付申请单号
*/
@SerializedName("applyment_id")
private String applymentId;
}

+ 18
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/AccountTypeEnum.java ファイルの表示

@@ -0,0 +1,18 @@
package com.github.binarywang.wxpay.bean.applyment.enums;


/**
* 银行结算账户枚举类
*/
public enum AccountTypeEnum {
/**
* 对公银行账户
*/
ACCOUNT_TYPE_BUSINESS,

/**
* 经营者个人银行卡
*/
ACCOUNT_TYPE_PRIVATE,
;
}

+ 42
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/ApplymentStateEnum.java ファイルの表示

@@ -0,0 +1,42 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 申请单状态枚举类
*
* @author zhouyongshen
*/
public enum ApplymentStateEnum {
/**
* (编辑中):提交申请发生错误导致,请尝试重新提交。
*/
APPLYMENT_STATE_EDITTING,
/**
* (审核中):申请单正在审核中,超级管理员用微信打开“签约链接”,完成绑定微信号后,申请单进度将通过微信公众号通知超级管理员,引导完成后续步骤。
*/
APPLYMENT_STATE_AUDITING,
/**
* (已驳回):请按照驳回原因修改申请资料,超级管理员用微信打开“签约链接”,完成绑定微信号,后续申请单进度将通过微信公众号通知超级管理员。
*/
APPLYMENT_STATE_REJECTED,
/**
* (待账户验证):请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成账户验证。
*/
APPLYMENT_STATE_TO_BE_CONFIRMED,
/**
* (待签约):请超级管理员使用微信打开返回的“签约链接”,根据页面指引完成签约。
*/
APPLYMENT_STATE_TO_BE_SIGNED,
/**
* (开通权限中):系统开通相关权限中,请耐心等待。
*/
APPLYMENT_STATE_SIGNING,
/**
* (已完成):商户入驻申请已完成。
*/
APPLYMENT_STATE_FINISHED,
/**
* (已作废):申请单已被撤销。
*/
APPLYMENT_STATE_CANCELED

}

+ 18
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/BankAccountTypeEnum.java ファイルの表示

@@ -0,0 +1,18 @@
package com.github.binarywang.wxpay.bean.applyment.enums;


/**
* 银行结算账户枚举类
*/
public enum BankAccountTypeEnum {
/**
* 对公银行账户
*/
BANK_ACCOUNT_TYPE_CORPORATE,

/**
* 经营者个人银行卡
*/
BANK_ACCOUNT_TYPE_PERSONAL,
;
}

+ 64
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/CertTypeEnum.java ファイルの表示

@@ -0,0 +1,64 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 登记证书的类型枚举
*/
public enum CertTypeEnum {
/**
* 事业单位法人证书
*/
CERTIFICATE_TYPE_2388,
/**
* 统一社会信用代码证书
*/
CERTIFICATE_TYPE_2389,
/**
* 有偿服务许可证(军队医院适用)
*/
CERTIFICATE_TYPE_2390,
/**
* 医疗机构执业许可证(军队医院适用)
*/
CERTIFICATE_TYPE_2391,
/**
* 企业营业执照(挂靠企业的党组织适用)
*/
CERTIFICATE_TYPE_2392,
/**
* 组织机构代码证(政府机关适用)
*/
CERTIFICATE_TYPE_2393,
/**
* 社会团体法人登记证书
*/
CERTIFICATE_TYPE_2394,
/**
* 民办非企业单位登记证书
*/
CERTIFICATE_TYPE_2395,
/**
* 基金会法人登记证书
*/
CERTIFICATE_TYPE_2396,
/**
* 宗教活动场所登记证
*/
CERTIFICATE_TYPE_2399,
/**
* 其他证书/批文/证明
*/
CERTIFICATE_TYPE_2400,
/**
* 执业许可证/执业证
*/
CERTIFICATE_TYPE_2520,
/**
* 基层群众性自治组织特别法人统一社会信用代码证
*/
CERTIFICATE_TYPE_2521,
/**
* 农村集体经济组织登记证
*/
CERTIFICATE_TYPE_2522,
;
}

+ 17
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/ContactTypeEnum.java ファイルの表示

@@ -0,0 +1,17 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 1、主体为“个体工商户/企业/政府机关/事业单位/社会组织”,可选择:LEGAL:经营者/法人,SUPER:经办人 。(经办人:经商户授权办理微信支付业务的人员)。
* 枚举值
*/
public enum ContactTypeEnum {
/**
* 法人
*/
LEGAL,
/**
* 经办人
*/
SUPER,
;
}

+ 20
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/IdHolderEnum.java ファイルの表示

@@ -0,0 +1,20 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 1. 主体类型为政府机关、事业单位时选传:
* (1)若上传的是法人证件,则不需要上传该字段
* (2)若因特殊情况,无法提供法人证件时,可上传经办人。 (经办人:经商户授权办理微信支付业务的人员,授权范围包括但不限于签约,入驻过程需完成账户验证)。
* 2. 主体类型为企业、个体户、社会组织时,默认为经营者/法人,不需要上传该字段。
* 枚举值
*/
public enum IdHolderEnum {
/**
* 法人
*/
LEGAL,
/**
* 经办人
*/
SUPER,
;
}

+ 41
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/IdTypeEnum.java ファイルの表示

@@ -0,0 +1,41 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 个体户/企业/党政、机关及事业单位/其他组织:可选择任一证件类型。
* 枚举值
*/
public enum IdTypeEnum {
/**
* 中国大陆居民-身份证
*/
IDENTIFICATION_TYPE_IDCARD,
/**
* 其他国家或地区居民-护照
*/
IDENTIFICATION_TYPE_OVERSEA_PASSPORT,
/**
* 中国香港居民-来往内地通行证
*/
IDENTIFICATION_TYPE_HONGKONG_PASSPORT,
/**
* 中国澳门居民-来往内地通行证
*/
IDENTIFICATION_TYPE_MACAO_PASSPORT,
/**
* 中国台湾居民-来往大陆通行证
*/
IDENTIFICATION_TYPE_TAIWAN_PASSPORT,
/**
* 外国人居留证
*/
IDENTIFICATION_TYPE_FOREIGN_RESIDENT,
/**
* 港澳居民证
*/
IDENTIFICATION_TYPE_HONGKONG_MACAO_RESIDENT,
/**
* 台湾居民证
*/
IDENTIFICATION_TYPE_TAIWAN_RESIDENT,
;
}

+ 20
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/MicroBizTypeEnum.java ファイルの表示

@@ -0,0 +1,20 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 小微经营类型
*/
public enum MicroBizTypeEnum {
/**
* 门店场所
*/
MICRO_TYPE_STORE,
/**
* 流动经营/便民服务
*/
MICRO_TYPE_MOBILE,
/**
* 线上商品/服务交易
*/
MICRO_TYPE_ONLINE,
;
}

+ 32
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SalesScenesTypeEnum.java ファイルの表示

@@ -0,0 +1,32 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 经营场景类型枚举值
*/
public enum SalesScenesTypeEnum {
/**
* 线下门店
*/
SALES_SCENES_STORE,
/**
* 公众号
*/
SALES_SCENES_MP,
/**
* 小程序
*/
SALES_SCENES_MINI_PROGRAM,
/**
* 互联网
*/
SALES_SCENES_WEB,
/**
* APP
*/
SALES_SCENES_APP,
/**
* 企业微信
*/
SALES_SCENES_WEWORK,
;
}

+ 23
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SettlementVerifyResultEnum.java ファイルの表示

@@ -0,0 +1,23 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 返回特约商户的结算账户-汇款验证结果枚举类
*
* @author zhouyognshen
*/
public enum SettlementVerifyResultEnum {
/**
* 系统汇款验证中,商户可发起提现尝试。
*/
VERIFYING,
/**
* 系统成功汇款,该账户可正常发起提现。
*/
VERIFY_SUCCESS,
/**
* 系统汇款失败,该账户无法发起提现,请检查修改。
*/
VERIFY_FAIL,
;

}

+ 34
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/applyment/enums/SubjectTypeEnum.java ファイルの表示

@@ -0,0 +1,34 @@
package com.github.binarywang.wxpay.bean.applyment.enums;

/**
* 主体类型枚举类
* <pre>
* 商户申请接入时如何选择主体类型? https://kf.qq.com/faq/180910IBZVnQ180910naQ77b.html
* </pre>
*
* @author zhouyongshen
*/
public enum SubjectTypeEnum {
/**
* (个体户):营业执照上的主体类型一般为个体户、个体工商户、个体经营;
*/
SUBJECT_TYPE_INDIVIDUAL,
/**
* (企业):营业执照上的主体类型一般为有限公司、有限责任公司;
*/
SUBJECT_TYPE_ENTERPRISE,
/**
* (党政、机关及事业单位):包括国内各级、各类政府机构、事业单位等(如:公安、党团、司法、交通、旅游、工商税务、市政、医疗、教育、学校等机构);
*/
SUBJECT_TYPE_INSTITUTIONS,
/**
* (其他组织):不属于企业、政府/事业单位的组织机构(如社会团体、民办非企业、基金会),要求机构已办理组织机构代码证。
*/
SUBJECT_TYPE_OTHERS,
/**
* (小微):无营业执照、免办理工商注册登记的实体商户
*/
SUBJECT_TYPE_MICRO,
;

}

+ 28
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankAccountResult.java ファイルの表示

@@ -0,0 +1,28 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
* 对私银行卡号开户银行信息
*
* @author zhongjun
**/
@Data
public class BankAccountResult implements Serializable {

private static final long serialVersionUID = -8226859146533243501L;

/**
* 根据卡号查询到的银行列表数据的总条数,未查询到对应银行列表时默认返回0,最大不超过两百条。
*/
@SerializedName("total_count")
private Integer totalCount;

@SerializedName("data")
private List<BankInfo> data;

}

+ 176
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankBranchesResult.java ファイルの表示

@@ -0,0 +1,176 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;

/**
* 支行列表
*
* @author hupeng
**/
@Data
public class BankBranchesResult implements Serializable {

private static final long serialVersionUID = -3500020131951579476L;

/**
* <pre>
* 字段名:查询数据总条数
* 变量名:total_count
* 是否必填:是
* 类型:int
* 描述:
* 经过条件筛选,查询到的支行总数
* 示例值:10
* </pre>
*/
@SerializedName("total_count")
private Integer totalCount;

/**
* <pre>
* 字段名:本次查询条数
* 变量名:count
* 是否必填:是
* 类型:int
* 描述:
* 本次查询到的支行数据条数
* 示例值:10
* </pre>
*/
@SerializedName("count")
private Integer count;

/**
* <pre>
* 字段名:支行列表
* 变量名:data
* 是否必填:否
* 类型:array
* 描述:
* 单次查询返回的支行列表结果数组
* </pre>
*/
@SerializedName("data")
private List<BankBranch> data;

/**
* <pre>
* 字段名:本次查询偏移量
* 变量名:offset
* 是否必填:是
* 类型:int
* 描述:
* 该次请求资源的起始位置,请求中包含偏移量时应答消息返回相同偏移量,否则返回默认值0
* 示例值:0
* </pre>
*/
@SerializedName("offset")
private Integer offset;

/**
* <pre>
* 字段名:分页链接
* 变量名:offset
* 是否必填:是
* 类型:object
* 描述:
* 返回前后页和当前页面的访问链接
* </pre>
*/
@SerializedName("links")
private PageLink links;

/**
* <pre>
* 字段名:开户银行
* 变量名:account_bank
* 是否必填:是
* 类型:string[1, 128]
* 描述:
* 查询到的支行所属开户银行的名称,非直连银行统一为其他银行
* 示例值:招商银行其他银行
* </pre>
*/
@SerializedName("account_bank")
private String accountBank;

/**
* <pre>
* 字段名:开户银行编码
* 变量名:account_bank_code
* 是否必填:是
* 类型:int
* 描述:
* 查询到的支行所属开户银行的开户银行编码,可用于付款到银行卡等场景中指定银行卡的开户银行
* 示例值:1001
* </pre>
*/
@SerializedName("account_bank_code")
private Integer accountBankCode;

/**
* <pre>
* 字段名:银行别名
* 变量名:bank_alias
* 是否必填:是
* 类型:string[1, 128]
* 描述:
* 查询到的支行所属银行的银行别名
* 示例值:工商银行深圳前海微众银行
* </pre>
*/
@SerializedName("bank_alias")
private String bankAlias;

/**
* <pre>
* 字段名:银行别名编码
* 变量名:bank_alias_code
* 是否必填:是
* 类型:string[1, 32]
* 描述:
* 查询到的支行所属银行的银行别名编码,用于校验回包
* 示例值:1000006247
* </pre>
*/
@SerializedName("bank_alias_code")
private String bankAliasCode;

@Getter
@Setter
public static class BankBranch {
/**
* <pre>
* 字段名:开户银行支行名称
* 变量名:bank_branch_name
* 是否必填:是
* 类型:string[1, 128]
* 描述:
* 开户银行支行名称,用于开户银行为其他银行的情况下,在入驻、修改结算银行卡、企业付款等场景下填写结算银行卡信息。
* 示例值:中国工商银行上海市周浦支行
* </pre>
*/
@SerializedName("bank_branch_name")
private String bankBranchName;

/**
* <pre>
* 字段名:开户银行支行联行号
* 变量名:bank_branch_id
* 是否必填:是
* 类型:string[1, 64]
* 描述:
* 开户银行支行的联行号,用于开户银行为其他银行的情况下,在入驻、修改结算银行卡、企业付款等场景下填写结算银行卡信息。
* 示例值:102290072311
* </pre>
*/
@SerializedName("bank_branch_id")
private String bankBranchId;
}
}

+ 39
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankInfo.java ファイルの表示

@@ -0,0 +1,39 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;

/**
* 银行信息
*
* @author zhongjun
* @date 2022/5/12
**/
@Data
public class BankInfo {
/**
* 银行别名
*/
@SerializedName("bank_alias")
private String bankAlias;
/**
* 银行别名编码
*/
@SerializedName("bank_alias_code")
private String bankAliasCode;
/**
* 开户银行
*/
@SerializedName("account_bank")
private String accountBank;
/**
* 开户银行编码
*/
@SerializedName("account_bank_code")
private Integer accountBankCode;
/**
* 是否需要填写支行
*/
@SerializedName("need_bank_branch")
private Boolean needBankBranch;
}

+ 64
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/BankingResult.java ファイルの表示

@@ -0,0 +1,64 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;

/**
* 个人业务的银行列表
*
* @author zhongjun
**/
@Data
public class BankingResult implements Serializable {
private static final long serialVersionUID = -8372812998971715894L;

/**
* 银行列表数据的总条数,调用方需要根据总条数分页查询
*/
@SerializedName("total_count")
private Integer totalCount;

/**
* 本次查询银行列表返回的数据条数
*/
@SerializedName("count")
private Integer count;

/**
* 该次请求资源的起始位置,请求中包含偏移量时应答消息返回相同偏移量,否则返回默认值0。
*/
@SerializedName("offset")
private Integer offset;

@SerializedName("data")
private List<BankInfo> data;

@SerializedName("links")
private Link links;

@Getter
@Setter
public static class Link {
/**
* 下一页链接
*/
@SerializedName("next")
private String next;
/**
* 上一页链接
*/
@SerializedName("prev")
private String prev;
/**
* 当前链接
*/
@SerializedName("self")
private String self;
}

}

+ 80
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/CitiesResult.java ファイルの表示

@@ -0,0 +1,80 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;

/**
* 城市列表
*
* @author hupeng
**/
@Data
public class CitiesResult implements Serializable {

private static final long serialVersionUID = -6089905695087974693L;

/**
* <pre>
* 字段名:查询数据总条数
* 变量名:total_count
* 是否必填:是
* 类型:int
* 描述:
* 查询到的省份数据总条数
* 示例值:10
* </pre>
*/
@SerializedName("total_count")
private Integer totalCount;

/**
* <pre>
* 字段名:城市列表
* 变量名:data
* 是否必填:否
* 类型:array
* 描述:
* 查询返回的城市列表结果
* </pre>
*/
@SerializedName("data")
private List<CityInfo> data;

@Getter
@Setter
public static class CityInfo {
/**
* <pre>
* 字段名:城市名称
* 变量名:city_name
* 是否必填:是
* 类型:string[1, 256]
* 描述:
* 城市名称
* 示例值:北京市
* </pre>
*/
@SerializedName("city_name")
private String cityName;

/**
* <pre>
* 字段名:城市编码
* 变量名:city_code
* 是否必填:是
* 类型:int
* 描述:
* 城市编码,唯一标识一座城市,用于结合银行别名编码查询支行列表
* 示例值:10
* </pre>
*/
@SerializedName("city_code")
private Integer cityCode;
}

}

+ 59
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/PageLink.java ファイルの表示

@@ -0,0 +1,59 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;

import java.io.Serializable;

/**
* 支行列表
*
* @author hupeng
**/
@Data
public class PageLink implements Serializable {

private static final long serialVersionUID = -2624233403271204837L;

/**
* <pre>
* 字段名:下一页链接
* 变量名:next
* 是否必填:否
* 类型:string[1, 2048]
* 描述:
* 使用同样的limit进行下一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果已经到最后时,为空
* 示例值:/v3/capital/capitallhh/banks/1001/branches?offset=10&limit=5
* </pre>
*/
@SerializedName("next")
private String next;

/**
* <pre>
* 字段名:上一页链接
* 变量名:prev
* 是否必填:否
* 类型:string[1, 2048]
* 描述:
* 使用同样的limit进行上一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果是第一页,为空
* 示例值:/v3/capital/capitallhh/banks/1001/branchesoffset=0&limit=5
* </pre>
*/
@SerializedName("prev")
private String prev;

/**
* <pre>
* 字段名:当前链接
* 变量名:self
* 是否必填:否
* 类型:string[1, 2048]
* 描述:
* 当前的相对请求链接,使用方需要自行根据当前域名进行拼接
* 示例值:/v3/capital/capitallhh/banks/1001/branches?offset=5&limit=5
* </pre>
*/
@SerializedName("self")
private String self;
}

+ 81
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/bank/ProvincesResult.java ファイルの表示

@@ -0,0 +1,81 @@
package com.github.binarywang.wxpay.bean.bank;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.List;

/**
* 省份列表
*
* @author hupeng
**/
@Data
public class ProvincesResult implements Serializable {

private static final long serialVersionUID = -4118613374545722650L;

/**
* <pre>
* 字段名:查询数据总条数
* 变量名:total_count
* 是否必填:是
* 类型:int
* 描述:
* 查询到的省份数据总条数
* 示例值:10
* </pre>
*/
@SerializedName("total_count")
private Integer totalCount;

/**
* <pre>
* 字段名:省份列表
* 变量名:data
* 是否必填:否
* 类型:array
* 描述:
* 查询到的省份列表数组
* </pre>
*/
@SerializedName("data")
private List<ProvinceInfo> data;

@Getter
@Setter
public static class ProvinceInfo {

/**
* <pre>
* 字段名:省份名称
* 变量名:province_name
* 是否必填:是
* 类型:string[1, 256]
* 描述:
* 省份名称
* 示例值:广东省
* </pre>
*/
@SerializedName("province_name")
private String provinceName;

/**
* <pre>
* 字段名:省份编码
* 变量名:province_code
* 是否必填:是
* 类型:int
* 描述:
* 省份编码,唯一标识一个省份,用于根据省份编码查询省份下的城市列表数据
* 示例值:22
* </pre>
*/
@SerializedName("province_code")
private Integer provinceCode;
}

}

+ 93
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/BusinessCircleNotifyData.java ファイルの表示

@@ -0,0 +1,93 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 智慧商圈回调通知对象
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_1.shtml
* https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_3.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class BusinessCircleNotifyData implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 通知ID
*/
@SerializedName("id")
private String id;

/**
* 通知创建时间
*/
@SerializedName("create_time")
private String createTime;

/**
* 通知类型
*/
@SerializedName("event_type")
private String eventType;

/**
* 通知数据类型
*/
@SerializedName("resource_type")
private String resourceType;

/**
* 回调摘要
* summary
*/
@SerializedName("summary")
private String summary;

/**
* 通知数据
*/
@SerializedName("resource")
private Resource resource;

@Data
public static class Resource implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 加密算法类型
*/
@SerializedName("algorithm")
private String algorithm;

/**
* 数据密文
*/
@SerializedName("ciphertext")
private String cipherText;

/**
* 附加数据
*/
@SerializedName("associated_data")
private String associatedData;

/**
* 随机串
*/
@SerializedName("nonce")
private String nonce;

/**
* 原始回调类型
*/
@SerializedName("original_type")
private String originalType;
}
}

+ 52
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeNotifyResult.java ファイルの表示

@@ -0,0 +1,52 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈授权结果通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_6.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardAuthorizeNotifyResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 会员在card_id下的唯一标识,
*/
@SerializedName("code")
private String code;

/**
* 用户开会员卡时的商圈商户号
*/
@SerializedName("mchid")
private String mchid;

/**
* 用户授权类型
* REGISTERED_MODE :会员开卡(进卡包) + 未授权会员积分服务
* REGISTERED_AND_AUTHORIZATION_MODE:会员开卡(进卡包)+授权会员积分服务
*/
@SerializedName("auth_type")
private String authType;

}

+ 53
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/MemberCardAuthorizeResult.java ファイルの表示

@@ -0,0 +1,53 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈授权结果查询内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_4.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardAuthorizeResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 顾客授权商圈积分结果
* UNAUTHORIZED:未授权
* AUTHORIZED:已授权
* DEAUTHORIZED:已取消授权
*/
@SerializedName("authorize_state")
private String authorizeState;

/**
* 顾客成功授权商圈积分的时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
*/
@SerializedName("authorize_time")
private String authorizeTime;

/**
* 顾客关闭授权商圈积分的时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
*/
@SerializedName("deauthorize_time")
private String deauthorizeTime;

}

+ 112
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PaidResult.java ファイルの表示

@@ -0,0 +1,112 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈支付结果通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_1.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class PaidResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 商户号
* <p>
* 微信支付分配的商户号
* 示例值:1230000109
*/
@SerializedName("mchid")
private String mchid;

/**
* 商圈商户名称
* <p>
* 商圈商户名称
* 示例值:微信支付
*/
@SerializedName("merchant_name")
private String merchantName;

/**
* 门店名称
* <p>
* 门店名称,商圈在商圈小程序上圈店时填写的门店名称
* 示例值:微信支付
*/
@SerializedName("shop_name")
private String shopName;

/**
* 门店编号
* <p>
* 门店编号,商圈在商圈小程序上圈店时填写的门店编号,用于跟商圈自身已有的商户识别码对齐
* 示例值:123456
*/
@SerializedName("shop_number")
private String shopNumber;

/**
* 小程序APPID
* <p>
* 顾客授权积分时使用的小程序的appid
* 示例值:wxd678efh567hg6787
*/
@SerializedName("appid")
private String appid;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 交易完成时间
* <p>
* 交易完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示北京时间2015年05月20日13点29分35秒(需要增加所有跟时间有关的参数的描述)
* 示例值:2015-05-20T13:29:35+08:00
*/
@SerializedName("time_end")
private String timeEnd;

/**
* 金额
* <p>
* 用户实际消费金额,单位(分)
* 示例值:200
*/
@SerializedName("amount")
private Integer amount;

/**
* 微信支付订单号
* <p>
* 微信支付订单号
* 示例值:1234567890
*/
@SerializedName("transaction_id")
private String transactionId;

/**
* 手动提交积分标记
* <p>
* 手动提交积分标记,自动提交时无该字段,用于区分用户手动申请后推送的积分数据
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWUHsd
*/
@SerializedName("commit_tag")
private String commitTag;
}

+ 103
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/ParkingNotifyRequest.java ファイルの表示

@@ -0,0 +1,103 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈停车同步
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_5.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ParkingNotifyRequest implements Serializable {

private static final long serialVersionUID = 1L;

/**
* <pre>
* 字段名:商圈商户ID
* 变量名:sub_mchid
* 是否必填:否
* 类型:string[1,64]
* 描述:
* 当以服务商模式管理商圈积分能力时,则要带上商圈商户ID,否则留空
* 示例值:1234567890
* </pre>
*/
@SerializedName(value = "sub_mchid")
private String subMchid;

/**
* <pre>
* 调用方商户号对应的品牌brandid,调用方商户号需为此品牌brandid的品牌主商户号或品牌服务商商户号
* </pre>
*/
@SerializedName(value = "brandid")
private String brandid;

/**
* <pre>
* 字段名:小程序appid
* 变量名:appid
* 是否必填:是
* 类型:string[1,128]
* 描述:
* 顾客授权积分时使用的小程序的appid
* 示例值:wx1234567890abcdef
* </pre>
*/
@SerializedName(value = "appid")
private String appid;

/**
* <pre>
* 字段名:用户标识
* 变量名:openid
* 是否必填:是
* 类型:string[1,64]
* 描述:
* 顾客授权时使用的小程序上的openid
* 示例值:oWmnN4xxxxxxxxxxe92NHIGf1xd8
* </pre>
*/
@SerializedName(value = "openid")
private String openid;

/**
* <pre>
* 首位需为省份的中文简称,第二位起支持大写字母、数字、中文
* </pre>
*/
@SerializedName(value = "plate_number")
private String plateNumber;

/**
* <pre>
* 停车状态,服务商模式下必传
* IN:入场,用户开车进入商圈
* OUT:离场,用户开车离开商圈
* </pre>
*/
@SerializedName(value = "state")
private String state;

/**
* <pre>
* 在场状态更新时间,按照使用rfc3339所定义的格式,格式为yyyy-MM-DDThh:mm:ss+TIMEZONE
* </pre>
*/
@SerializedName(value = "time")
private String time;

}

+ 31
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsCommitStatusResult.java ファイルの表示

@@ -0,0 +1,31 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈积分状态查询
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_7.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class PointsCommitStatusResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 商圈会员待积分状态
* PENDING:有积分待提交,商圈会员有待提交的积分记录,可引导会员跳转插件提交积分申请
* FINISHED:无积分可提交,商圈会员没有待提交的积分记录
*/
@SerializedName("points_commit_status")
private String pointsCommitStatus;

}

+ 154
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/PointsNotifyRequest.java ファイルの表示

@@ -0,0 +1,154 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈积分同步
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_2.shtml
* </pre>
*
* @author thinsstar
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PointsNotifyRequest implements Serializable {

private static final long serialVersionUID = 1L;

/**
* <pre>
* 字段名:商圈商户ID
* 变量名:sub_mchid
* 是否必填:否
* 类型:string[1,64]
* 描述:
* 当以服务商模式管理商圈积分能力时,则要带上商圈商户ID,否则留空
* 示例值:1234567890
* </pre>
*/
@SerializedName(value = "sub_mchid")
private String subMchid;

/**
* <pre>
* 字段名:微信订单号
* 变量名:transaction_id
* 是否必填:是
* 类型:string[1,64]
* 描述:
* 微信支付推送的商圈内交易通知里携带的微信订单号
* 示例值:1217752501201407033233368018
* </pre>
*/
@SerializedName(value = "transaction_id")
private String transactionId;

/**
* <pre>
* 字段名:小程序appid
* 变量名:appid
* 是否必填:是
* 类型:string[1,128]
* 描述:
* 顾客授权积分时使用的小程序的appid
* 示例值:wx1234567890abcdef
* </pre>
*/
@SerializedName(value = "appid")
private String appid;

/**
* <pre>
* 字段名:用户标识
* 变量名:openid
* 是否必填:是
* 类型:string[1,64]
* 描述:
* 顾客授权时使用的小程序上的openid
* 示例值:oWmnN4xxxxxxxxxxe92NHIGf1xd8
* </pre>
*/
@SerializedName(value = "openid")
private String openid;

/**
* <pre>
* 字段名:是否获得积分
* 变量名:earn_points
* 是否必填:是
* 类型:boolean
* 描述:
* 用于标明此单是否获得积分,
* true为获得积分,
* false为未获得
* 示例值:true
* </pre>
*/
@SerializedName(value = "earn_points")
private Boolean earnPoints;

/**
* <pre>
* 字段名:订单新增积分值
* 变量名:increased_points
* 是否必填:是
* 类型:int
* 描述:
* 顾客此笔交易新增的积分值
* 示例值:100
* </pre>
*/
@SerializedName(value = "increased_points")
private Integer increasedPoints;

/**
* <pre>
* 字段名:积分更新时间
* 变量名:points_update_time
* 是否必填:是
* 类型:string[1,32]
* 描述:
* 为顾客此笔交易成功积分的时间
* 示例值:2020-05-20T13:29:35.120+08:00
* </pre>
*/
@SerializedName(value = "points_update_time")
private String pointsUpdateTime;

/**
* <pre>
* 字段名:未获得积分的备注信息
* 变量名:no_points_remarks
* 是否必填:否
* 类型:string[1,128]
* 描述:
* 当未获得积分时,提供未获得积分的原因等备注信息
* 示例值:商品不参与积分活动
* </pre>
*/
@SerializedName(value = "no_points_remarks")
private String noPointsRemarks;

/**
* <pre>
* 字段名:顾客积分总额
* 变量名:total_points
* 是否必填:否
* 类型:int
* 描述:
* 当前顾客积分总额
* 示例值:888888
* </pre>
*/
@SerializedName(value = "total_points")
private Integer totalPoints;
}

+ 121
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/businesscircle/RefundResult.java ファイルの表示

@@ -0,0 +1,121 @@
package com.github.binarywang.wxpay.bean.businesscircle;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈退款成功通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_3.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class RefundResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 商户号
* <p>
* 微信支付分配的商户号
* 示例值:1230000109
*/
@SerializedName("mchid")
private String mchid;

/**
* 商圈商户名称
* <p>
* 商圈商户名称
* 示例值:微信支付
*/
@SerializedName("merchant_name")
private String merchantName;

/**
* 门店名称
* <p>
* 门店名称,商圈在商圈小程序上圈店时填写的门店名称
* 示例值:微信支付
*/
@SerializedName("shop_name")
private String shopName;

/**
* 门店编号
* <p>
* 门店编号,商圈在商圈小程序上圈店时填写的门店编号,用于跟商圈自身已有的商户识别码对齐
* 示例值:123456
*/
@SerializedName("shop_number")
private String shopNumber;

/**
* 小程序APPID
* <p>
* 顾客授权积分时使用的小程序的appid
* 示例值:wxd678efh567hg6787
*/
@SerializedName("appid")
private String appid;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 退款完成时间
* <p>
* 退款完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示北京时间2015年05月20日13点29分35秒(需要增加所有跟时间有关的参数的描述)
* 示例值:2015-05-20T13:29:35+08:00
*/
@SerializedName("refund_time")
private String refundTime;

/**
* 消费金额
* <p>
* 用户实际消费金额,单位(分)
* 示例值:100
*/
@SerializedName("pay_amount")
private Integer payAmount;

/**
* 退款金额
* <p>
* 用户退款金额,单位(分)
* 示例值:100
*/
@SerializedName("refund_amount")
private Integer refundAmount;

/**
* 微信支付订单号
* <p>
* 微信支付订单号
* 示例值:1234567890
*/
@SerializedName("transaction_id")
private String transactionId;

/**
* 微信支付退款单号
* <p>
* 微信支付退款单号
* 示例值:1217752501201407033233368999
*/
@SerializedName("refund_id")
private String refundId;
}

+ 35
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/ecommerce/SignatureHeader.java ファイルの表示

@@ -0,0 +1,35 @@
package com.github.binarywang.wxpay.bean.ecommerce;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 微信通知接口头部信息,需要做签名验证
* 文档地址: https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-yan-zheng
*/
@Data
@NoArgsConstructor
public class SignatureHeader implements Serializable {
private static final long serialVersionUID = -6958015499416059949L;
/**
* 时间戳
*/
private String timeStamp;

/**
* 随机串
*/
private String nonce;

/**
* 已签名字符串
*/
private String signed;

/**
* 证书序列号
*/
private String serialNo;
}

+ 28
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/ImageUploadResult.java ファイルの表示

@@ -0,0 +1,28 @@
package com.github.binarywang.wxpay.bean.media;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;

/**
* 媒体文件上传返回结果对象
* @author zhouyongshen
*/
@NoArgsConstructor
@Data
public class ImageUploadResult {

public static ImageUploadResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, ImageUploadResult.class);
}
/**
* 媒体文件标识 Id
*
* 微信返回的媒体文件标识Id。
* 示例值:6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0
*
*/
@SerializedName("media_id")
private String mediaId;
}

+ 29
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/media/MarketingImageUploadResult.java ファイルの表示

@@ -0,0 +1,29 @@
package com.github.binarywang.wxpay.bean.media;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;

/**
* 媒体文件上传返回结果对象
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MarketingImageUploadResult {

public static MarketingImageUploadResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, MarketingImageUploadResult.class);
}

/**
* 媒体文件URL地址
* <p>
* 微信返回的媒体文件标识url。有效期为永久
* 示例值:https://qpic.cn/xxx
*/
@SerializedName("media_url")
private String mediaUrl;
}

+ 82
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardActivateResult.java ファイルの表示

@@ -0,0 +1,82 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 商圈支付结果通知内容
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_32.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardActivateResult implements Serializable {

private static final long serialVersionUID = 1L;

/**
* 业务细分事件类型,枚举值:
* MEMBER_CARD_ACTIVATE:激活会员卡
*
* USER_VIEW_MEMBERCARD:用户查看会员卡详情
* USER_DELETE_MEMBERCARD:用户删除会员卡
* USER_MODIFY_INFORMATION:用户修改个人信息
*/
@SerializedName("event_type")
private String eventType;

/**
* 商户创建微信会员卡模板成功后系统返回的会员卡模板id
*/
@SerializedName("card_id")
private String cardId;

/**
* 会员在card_id下的唯一标识,
*/
@SerializedName("code")
private String code;

/**
* 事件发生时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss.sss+TIMEZONE
*/
@SerializedName("event_time")
private String eventTime;

/**
* 激活场景,用于区分用户新开卡激活或删卡后重新领取激活。枚举值:
* NEW_ACTIVATE 新开卡激活
* RECOVER 删卡后重新领取激活
*/
@SerializedName("activate_scene")
private String activateScene;

/**
* 用户标识
* <p>
* 顾客授权时使用的小程序上的openid
* 示例值:oUpF8uMuAJ2pxb1Q9zNjWeS6o
*/
@SerializedName("openid")
private String openid;

/**
* 微信用户在同一个微信开放平台账号下的唯一用户标识,unionid获取方式请参见《UnionID机制说明》文档。
*/
@SerializedName("unionid")
private String unionid;

/**
* 自定义场景值,商户可以用于标记投放场景,如门店/来源等。只能录入数字及中英文/半角标点
* 匹配正则表达式: ^[0-9a-zA-Z\u0000-\u00FF\u4e00-\u9fa5]+$
*/
@SerializedName("outer_str")
private String outerStr;

}

+ 93
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardNotifyData.java ファイルの表示

@@ -0,0 +1,93 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 会员卡回调通知对象
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_32.shtml
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_33.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardNotifyData implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 通知ID
*/
@SerializedName("id")
private String id;

/**
* 通知创建时间
*/
@SerializedName("create_time")
private String createTime;

/**
* 通知类型
*/
@SerializedName("event_type")
private String eventType;

/**
* 通知数据类型
*/
@SerializedName("resource_type")
private String resourceType;

/**
* 回调摘要
* summary
*/
@SerializedName("summary")
private String summary;

/**
* 通知数据
*/
@SerializedName("resource")
private Resource resource;

@Data
public static class Resource implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 加密算法类型
*/
@SerializedName("algorithm")
private String algorithm;

/**
* 数据密文
*/
@SerializedName("ciphertext")
private String cipherText;

/**
* 附加数据
*/
@SerializedName("associated_data")
private String associatedData;

/**
* 随机串
*/
@SerializedName("nonce")
private String nonce;

/**
* 原始回调类型
*/
@SerializedName("original_type")
private String originalType;
}
}

+ 360
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardResult.java ファイルの表示

@@ -0,0 +1,360 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
* 查询用户会员卡信息API
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_6.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardResult implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 商户创建微信会员卡模板成功后系统返回的会员卡模板id
*/
@SerializedName("card_id")
private String cardId;

/**
* 会员在card_id下的唯一标识,用户领取会员卡后获得的code
*/
@SerializedName("code")
private String code;

/**
* 用户在会员卡绑定品牌appid下的唯一标识,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("openid")
private String openid;

/**
* 在用户会员卡上展示的会员卡编号,默认使用会员卡code作为membership_number。只能录入数字/英文/半角标点。商家可通过修改用户单张会员卡信息更新
*/
@SerializedName("membership_number")
private String membershipNumber;

/**
* 用户会员等级
*/
@SerializedName("level")
private String level;

/**
* 用户的微信昵称,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("nickname")
private String nickname;

/**
* 用户的微信头像url,如通过手机号同步会员身份且用户未领取到卡包,无法查询该字段
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 商家给当前用户设置的会员卡背景图。仅支持通过《图片上传API》接口获取的图片URL地址。支持JPG/JPEG/PNG格式,且图片小于1M。
*/
@SerializedName("background_picture_url")
private String backgroundPictureUrl;

/**
* 用户储值的最新余额,单位分
*/
@SerializedName("balance")
private Integer balance;

/**
* 用户当前的卡状态:
* NOT_ACTIVATE:未激活
* EFFECTIVE:生效中
* EXPIRE:已过期
* UNAVAILABLE:已失效
* DELETE:已删除
* IMPORTED:已导入
*/
@SerializedName("user_card_status")
private String userCardStatus;

/**
* 用户开卡时填写的个人信息
*/
@SerializedName("user_information")
private UserInformation userInformation;

/**
* 用户当前的积分值
*/
@SerializedName("bonus_value")
private Integer bonusValue;

/**
* 用户当前的积分值
*/
@SerializedName("service_modules")
private List<ServiceModule> serviceModules;

/**
* 用户会员卡详情页会员优惠栏目中的会员专享价文案
*/
@SerializedName("member_price_word")
private String memberPriceWord;

/**
*发票栏跳转小程序的引导文案
*/
@SerializedName("fapiao_jump_word")
private String fapiaoJumpWord;

/**
*设置商家联系人员的名字、头像和联系方式
*/
@SerializedName("guide")
private List<Guide> guide;

@Data
public static class UserInformation implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 平台提供的通用开卡信息字段
* 包含性别、手机、头像、昵称、姓名等基本信息字段
*/
@SerializedName("common_field_list")
private List<CommonField> commonFieldList;

/**
* 商户自定义的开卡信息字段
*/
@SerializedName("custom_field_list")
private List<CustomField> customFieldList;

}

@Data
public static class CommonField implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 平台提供了一些通用的开卡字段供开发者选用
* USER_FORM_FLAG_MOBILE:手机号
* USER_FORM_FLAG_SEX:性别
* USER_FORM_FLAG_NAME:姓名
* USER_FORM_FLAG_BIRTHDAY:生日
* USER_FORM_FLAG_ADDRESS:地址
* USER_FORM_FLAG_EMAIL:邮箱
* USER_FORM_FLAG_CITY:城市
*/
@SerializedName("name")
private String name;

/**
* 平台提供的通用开卡信息字段,用户在开卡时填写的信息
*/
@SerializedName("value")
private String value;
}

@Data
public static class CustomField implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 商户自定义的开卡信息字段名称
*/
@SerializedName("name")
private String name;

/**
* 商户自定义的开卡信息字段值,用户在开卡时需填写。填写项目为单选时的返回
*/
@SerializedName("value")
private String value;

/**
* 商户自定义的开卡信息字段值,用户在开卡时需填写。填写项目为多选时的返回
* 特殊规则:列表最多支持10个,单个列表限制8个字符
*/
@SerializedName("value_list")
private List<String> valueList;
}

@Data
public static class ServiceModule implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 会员服务项的唯一识别ID,创建服务项后由微信支付生成的服务项ID。商户可通过服务项id查询服务项的配置信息及用途。
*/
@SerializedName("service_module_id")
private String serviceModuleId;

/**
* 用户的服务状态设置,这些设置会展示在用户的会员卡详情页。可设置状态的内容字段、按钮、消息内容等
*/
@SerializedName("state_setting")
private StateSetting stateSetting;

}

@Data
public static class StateSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 状态的id。一个服务项通常包含多个状态,商户可根据服务流程选择其中的状态进行设置,模板内容展示在用户的会员卡详情页,并支持通过公众号给用户发送触达消息
*/
@SerializedName("state_id")
private String stateId;

/**
* 用户的服务内容模板设置,这些设置会展示在用户的会员卡详情页。可设置状态的内容字段、按钮等
*/
@SerializedName("content_template_data")
private ContentTemplateData contentTemplateData;

/**
* 公众号模板消息设置。部分服务项支持给用户发送触达消息,商户可通过模板id选择模板消息样式,并设置字段值。API调用成功后会通过微信公众号自动给用户发送此模板消息。不填则默认不发消息
*/
@SerializedName("message_template_setting")
private MessageTemplateSetting messageTemplateSetting;
}

@Data
public static class ContentTemplateData implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 当前服务状态下,可以设置的内容字段列表
*/
@SerializedName("field_list")
private List<Field> fieldList;

/**
* 服务状态对应的操作设置,可配置跳转文案和跳转小程序路径
* 需配置跳转文案及跳转小程序路径时必填
*/
@SerializedName("action_setting")
private ActionSetting actionSetting;

}

@Data
public static class Field implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 服务内容列表,最多包含5条内容
*/
@SerializedName("field_id")
private String fieldId;

/**
* 服务状态字段的值
*/
@SerializedName("field_value")
private String fieldValue;

}

@Data
public static class ActionSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 操作名称
*/
@SerializedName("action_name")
private String actionName;

/**
* 服务状态指定跳转小程序
*/
@SerializedName("jump_miniprogram")
private JumpMiniprogram jumpMiniprogram;

}

@Data
public static class JumpMiniprogram implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 小程序的appid
*/
@SerializedName("appid")
private String appid;

/**
* 小程序的页面path
* 示例值:pages/index/index
*/
@SerializedName("path")
private String path;

}

@Data
public static class MessageTemplateSetting implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 公众号模板消息的id
*/
@SerializedName("message_template_id")
private String messageTemplateId;

/**
* 模板消息字段列表。商户在此设置模板消息每个字段需展示的内容
* 特殊规则:限制最多可提交9条
*/
@SerializedName("field_list")
private List<Field> fieldList;

}

@Data
public static class Guide implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 设置商家咨询联系人的名称
*/
@SerializedName("staff_name")
private String staffName;

/**
* 设置商家咨询联系人的头像。仅支持通过《图片上传API》接口获取的图片URL地址。
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 展示说明商家咨询联系人的联系方式,例如“微信号”“企业微信号”
*/
@SerializedName("contact_information_name")
private String contactInformationName;

/**
* 展示说明商家咨询联系人的联系方式信息,例如“weixin123”“135266664”
*/
@SerializedName("contact_information_value")
private String contactInformationValue;

/**
* 商家咨询联系人的联系电话
*/
@SerializedName("phone_number")
private String phoneNumber;
}
}

+ 104
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardRightsRequest.java ファイルの表示

@@ -0,0 +1,104 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
* 设置用户会员权益信息api
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_23.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardRightsRequest implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 变更前的用户的积分值
*/
@SerializedName("before_bonus_value")
private Integer beforeBonusValue;

/**
* 变更后的用户最新积分值,该值会展示在会员卡详页上
*/
@SerializedName("bonus_value")
private Integer bonusValue;

/**
* 本次变更的积分值
*/
@SerializedName("add_bonus_value")
private Integer addBonusValue;

/**
* 商户凭据号。商户自定义,注意保持唯一性,仅供参考的格式:商户id+日期+流水号。可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。
*/
@SerializedName("out_request_no")
private String outRequestNo;

/**
* 积分变更时是否触发系统模板消息,默认为true
*/
@SerializedName("need_inform_bonus")
private Boolean needInformBonus;

/**
* 用户会员卡详情页会员优惠栏目中的会员专享价文案
*/
@SerializedName("member_price_word")
private String memberPriceWord;

/**
*发票栏跳转小程序的引导文案
*/
@SerializedName("fapiao_jump_word")
private String fapiaoJumpWord;

/**
*设置商家联系人员的名字、头像和联系方式
*/
@SerializedName("guide")
private Guide guide;

@Data
public static class Guide implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 设置商家咨询联系人的名称
*/
@SerializedName("staff_name")
private String staffName;

/**
* 设置商家咨询联系人的头像。仅支持通过《图片上传API》接口获取的图片URL地址。
*/
@SerializedName("head_image_url")
private String headImageUrl;

/**
* 展示说明商家咨询联系人的联系方式,例如“微信号”“企业微信号”
*/
@SerializedName("contact_information_name")
private String contactInformationName;

/**
* 展示说明商家咨询联系人的联系方式信息,例如“weixin123”“135266664”
*/
@SerializedName("contact_information_value")
private String contactInformationValue;

/**
* 商家咨询联系人的联系电话
*/
@SerializedName("phone_number")
private String phoneNumber;
}
}

+ 95
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/membercard/MemberCardUpdRequest.java ファイルの表示

@@ -0,0 +1,95 @@
package com.github.binarywang.wxpay.bean.membercard;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
* 修改用户会员卡信息API
* <pre>
* 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_8.shtml
* </pre>
*
* @author thinsstar
*/
@NoArgsConstructor
@Data
public class MemberCardUpdRequest implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 在用户会员卡上展示的会员卡编号,默认使用会员卡code作为membership_number。只能录入数字/英文/半角标点。商家可通过修改用户单张会员卡信息更新
*/
@SerializedName("membership_number")
private String membershipNumber;

/**
* 商家给当前用户设置的会员卡背景图。仅支持通过《图片上传API》接口获取的图片URL地址。支持JPG/JPEG/PNG格式,且图片小于1M。
*/
@SerializedName("background_picture_url")
private String backgroundPictureUrl;

/**
* 用户会员等级
*/
@SerializedName("level")
private String level;

/**
* 商户据号。商户自定义,注意保持唯一性,仅供参考的格式:商户id+日期+流水号。可包含英文字母,数字,|,_,*,-等内容,不允许出现其他不合法符号。
*/
@SerializedName("out_request_no")
private String outRequestNo;

/**
* 用户储值变更信息
*/
@SerializedName("balance_information")
private BalanceInformation balanceInformation;

/**
* 用户储值变更信息
*/
@SerializedName("need_inform_balance")
private Boolean needInformBalance;

/**
* 用户储值变更信息
*/
@SerializedName("need_inform_level")
private Boolean needInformLevel;


@Data
public static class BalanceInformation implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 用户储值的更新前余额,单位分
*/
@SerializedName("before_balance")
private Integer beforeBalance;

/**
* 用户储值的更新后余额,单位分
*/
@SerializedName("balance")
private Integer balance;

/**
* 用户储值余额本次的变动值,单位分,等于balance减去before_balance,传入正数表示余额增加,传入负数表示余额减少
*/
@SerializedName("add_balance")
private Integer addBalance;

/**
* 商家自定义储值金额消耗记录,不超过30个字
*/
@SerializedName("balance_remark")
private String balanceRemark;

}
}

+ 178
- 34
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java ファイルの表示

@@ -1,15 +1,27 @@
package com.github.binarywang.wxpay.config;

import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.v3.WxPayV3HttpClientBuilder;
import com.github.binarywang.wxpay.v3.auth.*;
import com.github.binarywang.wxpay.v3.util.PemUtils;
import jodd.util.ResourcesUtil;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collections;

/**
* 微信支付配置
@@ -17,8 +29,11 @@ import java.security.KeyStore;
* @author Binary Wang (https://github.com/binarywang)
*/
@Data
@EqualsAndHashCode(exclude = "verifier")
public class WxPayConfig {
private static final String DEFAULT_PAY_BASE_URL = "https://api.mch.weixin.qq.com";
private static final String PROBLEM_MSG = "证书文件【%s】有问题,请核实!";
private static final String NOT_FOUND_MSG = "证书文件【%s】不存在,请核实!";

/**
* 微信支付接口请求地址域名部分.
@@ -85,6 +100,52 @@ public class WxPayConfig {
*/
private String keyPath;

/**
* apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径.
*/
private String privateKeyPath;
/**
* apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径.
*/
private String privateCertPath;

/**
* apiV3 秘钥值.
*/
private String apiV3Key;

/**
* apiV3 证书序列号值
*/
private String certSerialNo;
/**
* 微信支付分serviceId
*/
private String serviceId;

/**
* 微信支付分回调地址
*/
private String payScoreNotifyUrl;


/**
* 微信支付分授权回调地址
*/
private String payScorePermissionNotifyUrl;


private CloseableHttpClient apiV3HttpClient;
/**
* 私钥信息
*/
private PrivateKey privateKey;

/**
* 证书自动更新时间差(分钟),默认一分钟
*/
private int certAutoUpdateTime = 60;

/**
* p12证书文件内容的字节数组.
*/
@@ -106,8 +167,15 @@ public class WxPayConfig {
private String httpProxyUsername;
private String httpProxyPassword;

/**
* v3接口下证书检验对象,通过改对象可以获取到X509Certificate,进一步对敏感信息加密
* 文档见 https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/min-gan-xin-xi-jia-mi
*/
private Verifier verifier;

/**
* 返回所设置的微信支付接口请求地址域名.
*
* @return 微信支付接口请求地址域名
*/
public String getPayBaseUrl() {
@@ -118,6 +186,15 @@ public class WxPayConfig {
return this.payBaseUrl;
}

@SneakyThrows
public Verifier getVerifier() {
if (verifier == null) {
//当改对象为null时,初始化api v3的请求头
initApiV3HttpClient();
}
return verifier;
}

/**
* 初始化ssl.
*
@@ -136,40 +213,7 @@ public class WxPayConfig {
if (StringUtils.isBlank(this.getKeyPath())) {
throw new WxPayException("请确保证书文件地址keyPath已配置");
}

final String prefix = "classpath:";
String fileHasProblemMsg = "证书文件【" + this.getKeyPath() + "】有问题,请核实!";
String fileNotFoundMsg = "证书文件【" + this.getKeyPath() + "】不存在,请核实!";
if (this.getKeyPath().startsWith(prefix)) {
String path = StringUtils.removeFirst(this.getKeyPath(), prefix);
if (!path.startsWith("/")) {
path = "/" + path;
}
inputStream = WxPayConfig.class.getResourceAsStream(path);
if (inputStream == null) {
throw new WxPayException(fileNotFoundMsg);
}
} else if (this.getKeyPath().startsWith("http://") || this.getKeyPath().startsWith("https://")) {
try {
inputStream = new URL(this.keyPath).openStream();
if (inputStream == null) {
throw new WxPayException(fileNotFoundMsg);
}
} catch (IOException e) {
throw new WxPayException(fileNotFoundMsg, e);
}
} else {
try {
File file = new File(this.getKeyPath());
if (!file.exists()) {
throw new WxPayException(fileNotFoundMsg);
}

inputStream = new FileInputStream(file);
} catch (IOException e) {
throw new WxPayException(fileHasProblemMsg, e);
}
}
inputStream = this.loadConfigInputStream(this.getKeyPath());
}

try {
@@ -185,4 +229,104 @@ public class WxPayConfig {
}
}

/**
* 初始化api v3请求头 自动签名验签
* 方法参照微信官方https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient
*
* @return org.apache.http.impl.client.CloseableHttpClient
* @author doger.wang
**/
public CloseableHttpClient initApiV3HttpClient() throws WxPayException {
String privateKeyPath = this.getPrivateKeyPath();
String privateCertPath = this.getPrivateCertPath();
String serialNo = this.getCertSerialNo();
String apiV3Key = this.getApiV3Key();
if (StringUtils.isBlank(privateKeyPath)) {
throw new WxPayException("请确保privateKeyPath已设置");
}
if (StringUtils.isBlank(privateCertPath)) {
throw new WxPayException("请确保privateCertPath已设置");
}
// if (StringUtils.isBlank(certSerialNo)) {
// throw new WxPayException("请确保certSerialNo证书序列号已设置");
// }
if (StringUtils.isBlank(apiV3Key)) {
throw new WxPayException("请确保apiV3Key值已设置");
}

InputStream keyInputStream = this.loadConfigInputStream(privateKeyPath);
InputStream certInputStream = this.loadConfigInputStream(privateCertPath);
try {
PrivateKey merchantPrivateKey = PemUtils.loadPrivateKey(keyInputStream);
X509Certificate certificate = PemUtils.loadCertificate(certInputStream);
if(StringUtils.isBlank(serialNo)){
this.certSerialNo = certificate.getSerialNumber().toString(16).toUpperCase();
}

AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
new WxPayCredentials(mchId, new PrivateKeySigner(certSerialNo, merchantPrivateKey)),
apiV3Key.getBytes(StandardCharsets.UTF_8), this.getCertAutoUpdateTime());

CloseableHttpClient httpClient = WxPayV3HttpClientBuilder.create()
.withMerchant(mchId, certSerialNo, merchantPrivateKey)
.withWechatpay(Collections.singletonList(certificate))
.withValidator(new WxPayValidator(verifier))
.build();
this.apiV3HttpClient = httpClient;
this.verifier=verifier;
this.privateKey = merchantPrivateKey;

return httpClient;
} catch (Exception e) {
throw new WxPayException("v3请求构造异常!", e);
}
}

/**
* 从配置路径 加载配置 信息(支持 classpath、本地路径、网络url)
* @param configPath 配置路径
* @return
* @throws WxPayException
*/
private InputStream loadConfigInputStream(String configPath) throws WxPayException {
InputStream inputStream;
final String prefix = "classpath:";
String fileHasProblemMsg = String.format(PROBLEM_MSG, configPath);
String fileNotFoundMsg = String.format(NOT_FOUND_MSG, configPath);
if (configPath.startsWith(prefix)) {
String path = RegExUtils.removeFirst(configPath, prefix);
if (!path.startsWith("/")) {
path = "/" + path;
}
try {
inputStream = ResourcesUtil.getResourceAsStream(path);
if (inputStream == null) {
throw new WxPayException(fileNotFoundMsg);
}
} catch (Exception e) {
throw new WxPayException(fileNotFoundMsg, e);
}
} else if (configPath.startsWith("http://") || configPath.startsWith("https://")) {
try {
inputStream = new URL(configPath).openStream();
if (inputStream == null) {
throw new WxPayException(fileNotFoundMsg);
}
} catch (IOException e) {
throw new WxPayException(fileNotFoundMsg, e);
}
} else {
try {
File file = new File(configPath);
if (!file.exists()) {
throw new WxPayException(fileNotFoundMsg);
}

inputStream = new FileInputStream(file);
} catch (IOException e) {
throw new WxPayException(fileHasProblemMsg, e);
}
}
return inputStream;
}
}

+ 74
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/Applyment4SubService.java ファイルの表示

@@ -0,0 +1,74 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.applyment.*;
import com.github.binarywang.wxpay.exception.WxPayException;

/**
* 特约商户进件
* 产品介绍:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter1_1.shtml
*
* @author zhouyongshen
*/
public interface Applyment4SubService {
/**
* 提交申请单API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_1.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/
*
* @param request 请求对象
* @return WxPayApplymentCreateResult 响应结果
* @throws WxPayException the wx pay exception
*/
WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException;

/**
* 通过业务申请编号查询申请状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_2.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/{business_code}
*
* @param businessCode 业务申请编号
* 1、只能由数字、字母或下划线组成,建议前缀为服务商商户号。
* 2、服务商自定义的唯一编号。
* 3、每个编号对应一个申请单,每个申请单审核通过后生成一个微信支付商户号。
* 4、若申请单被驳回,可填写相同的“业务申请编号”,即可覆盖修改原申请单信息。
* 示例值:1900013511_10000
* @return the applyment state query result
* @throws WxPayException the wx pay exception
*/
ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException;

/**
* 通过申请单号查询申请状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_2.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/applyment_id/{applyment_id}
*
* @param applymentId 微信支付分的申请单号。示例值:2000001234567890
* @return the applyment state query result
* @throws WxPayException the wx pay exception
*/
ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException;

/**
* 通过商户号查询结算帐号状态
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_4.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/{sub_mchid}/settlement
*
* @param subMchid 本服务商进件、已签约的特约商户号。
* @return the settlement info result
* @throws WxPayException the wx pay exception
*/
SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException;

/**
* 修改结算帐号
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/applyment4sub/chapter3_3.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/apply4sub/sub_merchants/{sub_mchid}/modify-settlement
*
* @param subMchid 特约商户号
* @param request 修改结算账户请求对象信息
* @throws WxPayException the wx pay exception
* @return
*/
String modifySettlement(String subMchid, ModifySettlementRequest request) throws WxPayException;

}

+ 121
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BankService.java ファイルの表示

@@ -0,0 +1,121 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.bank.*;
import com.github.binarywang.wxpay.exception.WxPayException;

/**
* <pre>
* 微信支付-银行组件
* </pre>
*
* @author zhongjun
**/
public interface BankService {
/**
* <pre>
*
* 获取对私银行卡号开户银行
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/search-banks-by-bank-account">https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/search-banks-by-bank-account</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_1.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_1.shtml</a>
* </pre>
*
* @param accountNumber 银行卡号 该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
* @return BankAccountResult 对私银行卡号开户银行信息
* @throws WxPayException .
*/
BankAccountResult searchBanksByBankAccount(String accountNumber) throws WxPayException;

/**
* <pre>
*
* 查询支持个人业务的银行列表
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/personal-banking">https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/personal-banking</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_2.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_2.shtml</a>
* </pre>
*
* @param offset 本次查询偏移量
* @param limit 本次请求最大查询条数,最大值为200
* @return PersonalBankingResult 支持个人业务的银行列表信息
* @throws WxPayException .
*/
BankingResult personalBanking(Integer offset, Integer limit) throws WxPayException;

/**
* <pre>
*
* 支持对公业务的银行列表
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/corporate-banking">https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/corporate-banking</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_3.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_3.shtml</a>
* </pre>
*
* @param offset 本次查询偏移量
* @param limit 本次请求最大查询条数,最大值为200
* @return BankingResult 支持对公业务的银行列表信息
* @throws WxPayException .
*/
BankingResult corporateBanking(Integer offset, Integer limit) throws WxPayException;

/**
* <pre>
*
* 查询省份列表API
* 通过本接口获取省份列表数据(不包含中国港澳台地区),可用于省份下的城市数据查询
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces">https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_4.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_4.shtml</a>
* </pre>
*
* @return ProvincesResult 省份列表信息
* @throws WxPayException .
*/
ProvincesResult areasProvinces() throws WxPayException;

/**
* <pre>
*
* 查询城市列表API
* 通过本接口根据省份编码获取省份下的城市列表信息,不包含中国港澳台地区城市信息,可用于支行数据过滤查询
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces/{province_code}/cities">https://api.mch.weixin.qq.com/v3/capital/capitallhh/areas/provinces/{province_code}/cities</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_5.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_5.shtml</a>
* </pre>
*
* @return CitiesResult 城市列表信息
* @throws WxPayException .
*/
CitiesResult areasCities(Integer provinceCode) throws WxPayException;

/**
* <pre>
*
* 查询支行列表API
* 本接口可以用于根据银行别名编码(仅支持需要填写支行的银行别名编码)和城市编码过滤查询支行列表数据
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/{bank_alias_code}/branches">https://api.mch.weixin.qq.com/v3/capital/capitallhh/banks/{bank_alias_code}/branches</a>
*
* 文档地址:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_5.shtml">https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter11_2_5.shtml</a>
* </pre>
*
* @param bankAliasCode 银行别名的编码,查询支行接口仅支持需要填写支行的银行别名编码。示例值:1000006247
* @param cityCode 城市编码,唯一标识一座城市,用于结合银行别名编码查询支行列表。示例值:536
* @param offset 非负整数,表示该次请求资源的起始位置,从0开始计数。调用方选填,默认为0。offset为20,limit为100时,查询第21-120条数据
* @param limit 非0非负的整数,该次请求可返回的最大资源条数。示例值:200
* @return BankBranchesResult 城市列表信息
* @throws WxPayException .
*/
BankBranchesResult bankBranches(String bankAliasCode, Integer cityCode, Integer offset, Integer limit) throws WxPayException;
}

+ 59
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/BusinessCircleService.java ファイルの表示

@@ -0,0 +1,59 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.businesscircle.*;
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.exception.WxPayException;

/**
* <pre>
* 微信支付智慧商圈API
* </pre>
*
* @author thinsstar
*/
public interface BusinessCircleService {
/**
* <pre>
* 智慧商圈接口-商圈积分同步API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/businesscircle/chapter3_2.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/businesscircle/points/notify
* </pre>
*
* @param request 请求对象
* @throws WxPayException the wx pay exception
*/
String notifyPoints(PointsNotifyRequest request) throws WxPayException;

BusinessCircleNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException;

PaidResult decryptPaidNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

RefundResult decryptRefundNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

MemberCardAuthorizeNotifyResult decryptMemberCardAuthorizeNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException;

/**
* 授权查询
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_4.shtml
* @return
* @throws WxPayException
*/
MemberCardAuthorizeResult getAuthorizations(String openid) throws WxPayException;

/**
* 查询待积分状态
* @param brandid
* @param openid
* @return
* @throws WxPayException
*/
PointsCommitStatusResult getPointsCommitStatus(String brandid,String openid) throws WxPayException;

/**
* 停车状态同步
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_6_5.shtml
* @param request
* @throws WxPayException
*/
void notifyParkings(ParkingNotifyRequest request) throws WxPayException;
}

+ 50
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MemberCardService.java ファイルの表示

@@ -0,0 +1,50 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.bean.membercard.*;
import com.github.binarywang.wxpay.exception.WxPayException;

/**
* <pre>
* 会员卡相关接口
* </pre>
*
* @author thinsstar
*/
public interface MemberCardService {

MemberCardNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException;

MemberCardActivateResult decryptActivateNotifyDataResource(MemberCardNotifyData data) throws WxPayException;

/**
* 查询会员卡信息
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_6.shtml
* @param card_id
* @param code
* @return
* @throws WxPayException
*/
MemberCardResult getMemberCard(String card_id,String code) throws WxPayException;

/**
* 修改用户会员卡信息API
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_8.shtml
* @param card_id
* @param code
* @param request
* @throws WxPayException
*/
void updMemberCard(String card_id, String code, MemberCardUpdRequest request) throws WxPayException;

/**
* 设置用户会员权益信息api
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter5_9_23.shtml
* @param card_id
* @param code
* @param request
* @throws WxPayException
*/
void setMemberCardRights(String card_id,String code,MemberCardRightsRequest request) throws WxPayException;

}

+ 46
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/MerchantMediaService.java ファイルの表示

@@ -0,0 +1,46 @@
package com.github.binarywang.wxpay.service;

import com.github.binarywang.wxpay.bean.media.ImageUploadResult;
import com.github.binarywang.wxpay.exception.WxPayException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
* <pre>
* 微信支付通用媒体接口.
* </pre>
*
* @author zhouyongshen
*/
public interface MerchantMediaService {
/**
* <pre>
* 通用接口-图片上传API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/chapter3_1.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/merchant/media/upload
* </pre>
*
* @param imageFile 需要上传的图片文件
* @return ImageUploadResult 微信返回的媒体文件标识Id。示例值:6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0
* @throws WxPayException the wx pay exception
*/
ImageUploadResult imageUploadV3(File imageFile) throws WxPayException, IOException;

/**
* <pre>
* 通用接口-图片上传API
* 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/tool/chapter3_1.shtml
* 接口链接:https://api.mch.weixin.qq.com/v3/merchant/media/upload
* </pre>
*
* @param inputStream 需要上传的图片文件流
* @param fileName 需要上传的图片文件名
* @return ImageUploadResult 微信返回的媒体文件标识Id。示例值:6uqyGjGrCf2GtyXP8bxrbuH9-aAoTjH-rKeSl3Lf4_So6kdkQu4w8BYVP3bzLtvR38lxt4PjtCDXsQpzqge_hQEovHzOhsLleGFQVRF-U_0
* @throws WxPayException the wx pay exception
*/
ImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException;


}

+ 120
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java ファイルの表示

@@ -9,8 +9,11 @@ import com.github.binarywang.wxpay.bean.request.*;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;

import java.io.File;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;

@@ -53,6 +56,87 @@ public interface WxPayService {
*/
String post(String url, String requestStr, boolean useKey) throws WxPayException;

/**
* 发送post请求,得到响应字符串.
*
* @param url 请求地址
* @param requestStr 请求信息
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String postV3(String url, String requestStr) throws WxPayException;

/**
* 发送patch请求,得到响应字符串.
*
* @param url 请求地址
* @param requestStr 请求信息
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String patchV3(String url, String requestStr) throws WxPayException;

/**
* 发送post请求,得到响应字符串.
* <p>
* 部分字段会包含敏感信息,所以在提交前需要在请求头中会包含"Wechatpay-Serial"信息
*
* @param url 请求地址
* @param requestStr 请求信息
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String postV3WithWechatpaySerial(String url, String requestStr) throws WxPayException;

/**
* 发送post请求,得到响应字符串.
*
* @param url 请求地址
* @param httpPost 请求信息
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String postV3(String url, HttpPost httpPost) throws WxPayException;

/**
* 发送http请求,得到响应字符串.
*
* @param url 请求地址
* @param httpRequest 请求信息,可以是put,post,get,delete等请求
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String requestV3(String url, HttpRequestBase httpRequest) throws WxPayException;

/**
* 发送get V3请求,得到响应字符串.
*
* @param url 请求地址
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String getV3(String url) throws WxPayException;

/**
* 发送get请求,得到响应字符串.
* <p>
* 部分字段会包含敏感信息,所以在提交前需要在请求头中会包含"Wechatpay-Serial"信息
*
* @param url 请求地址
* @return 返回请求结果字符串 string
* @throws WxPayException the wx pay exception
*/
String getV3WithWechatPaySerial(String url) throws WxPayException;

/**
* 发送下载 V3请求,得到响应流.
*
* @param url 请求地址
* @return 返回请求响应流 input stream
* @throws WxPayException the wx pay exception
*/
InputStream downloadV3(String url) throws WxPayException;

/**
* 获取企业付款服务类.
*
@@ -74,6 +158,41 @@ public interface WxPayService {
*/
ProfitSharingService getProfitSharingService();

/**
* 获取微信支付智慧商圈服务类
*
* @return the business circle service
*/
BusinessCircleService getBusinessCircleService();

/**
* 获取会员卡服务类
*
* @return the business circle service
*/
MemberCardService getMemberCardService();

/**
* 特约商户进件服务
*
* @return
*/
Applyment4SubService getApplyment4SubService();

/**
* 媒体上传服务
*
* @return
*/
MerchantMediaService getMerchantMediaService();

/**
* 获取银行组件服务
*
* @return 银行组件服务
*/
BankService getBankService();

/**
* 设置企业付款服务类,允许开发者自定义实现类.
*
@@ -81,6 +200,7 @@ public interface WxPayService {
*/
void setEntPayService(EntPayService entPayService);


/**
* <pre>
* 查询订单.


+ 66
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/Applyment4SubServiceImpl.java ファイルの表示

@@ -0,0 +1,66 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.applyment.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.Applyment4SubService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.security.cert.X509Certificate;

@Slf4j
@RequiredArgsConstructor
public class Applyment4SubServiceImpl implements Applyment4SubService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;

private void encryptFiled(Object request) throws WxPayException {

X509Certificate validCertificate = payService.getConfig().getVerifier().getValidCertificate();

RsaCryptoUtil.encryptFields(request, validCertificate);
}


@Override
public WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/", this.payService.getPayBaseUrl());

encryptFiled(request);

String result = payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
return GSON.fromJson(result, WxPayApplymentCreateResult.class);
}

@Override
public ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/business_code/%s", this.payService.getPayBaseUrl(), businessCode);
String result = payService.getV3(url);
return GSON.fromJson(result, ApplymentStateQueryResult.class);
}

@Override
public ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException {
String url = String.format("%s/v3/applyment4sub/applyment/applyment_id/%s", this.payService.getPayBaseUrl(), applymentId);
String result = payService.getV3(url);
return GSON.fromJson(result, ApplymentStateQueryResult.class);
}

@Override
public SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/settlement", this.payService.getPayBaseUrl(), subMchid);
String result = payService.getV3(url);
return GSON.fromJson(result, SettlementInfoResult.class);
}

@Override
public String modifySettlement(String subMchid, ModifySettlementRequest request) throws WxPayException {
String url = String.format("%s/v3/apply4sub/sub_merchants/%s/modify-settlement", this.payService.getPayBaseUrl(), subMchid);
encryptFiled(request);
return payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
}

+ 68
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BankServiceImpl.java ファイルの表示

@@ -0,0 +1,68 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.bank.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.BankService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;

/**
* 微信支付-银行组件
*
* @author zhongjun
**/
@RequiredArgsConstructor
public class BankServiceImpl implements BankService {
private final WxPayService payService;
private static final Gson GSON = new GsonBuilder().create();

@Override
public BankAccountResult searchBanksByBankAccount(String accountNumber) throws WxPayException {
String url = String.format("%s/v3/capital/capitallhh/banks/search-banks-by-bank-account?account_number=%s", this.payService.getPayBaseUrl(), accountNumber);
String response = payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, BankAccountResult.class);
}

@Override
public BankingResult personalBanking(Integer offset, Integer limit) throws WxPayException {
offset = offset == null ? 0 : offset;
limit = limit == null ? 200 : limit;
String url = String.format("%s/v3/capital/capitallhh/banks/personal-banking?offset=%s&limit=%s", this.payService.getPayBaseUrl(), offset, limit);
String response = payService.getV3(url);
return GSON.fromJson(response, BankingResult.class);
}

@Override
public BankingResult corporateBanking(Integer offset, Integer limit) throws WxPayException {
offset = offset == null ? 0 : offset;
limit = limit == null ? 200 : limit;
String url = String.format("%s/v3/capital/capitallhh/banks/corporate-banking?offset=%s&limit=%s", this.payService.getPayBaseUrl(), offset, limit);
String response = payService.getV3(url);
return GSON.fromJson(response, BankingResult.class);
}

@Override
public ProvincesResult areasProvinces() throws WxPayException {
String url = String.format("%s/v3/capital/capitallhh/areas/provinces", this.payService.getPayBaseUrl());
String response = payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, ProvincesResult.class);
}

@Override
public CitiesResult areasCities(Integer provinceCode) throws WxPayException {
String url = String.format("%s/v3/capital/capitallhh/areas/provinces/%s/cities", this.payService.getPayBaseUrl(), provinceCode);
String response = payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response, CitiesResult.class);
}

@Override
public BankBranchesResult bankBranches(String bankAliasCode, Integer cityCode, Integer offset, Integer limit) throws WxPayException {
offset = offset == null ? 0 : offset;
limit = limit == null ? 200 : limit;
String url = String.format("%s/v3/capital/capitallhh/banks/%s/branches?city_code=%s&offset=%s&limit=%s", this.payService.getPayBaseUrl(), bankAliasCode, cityCode, offset, limit);
String response = payService.getV3(url);
return GSON.fromJson(response, BankBranchesResult.class);
}
}

+ 31
- 4
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java ファイルの表示

@@ -16,10 +16,7 @@ import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.EntPayService;
import com.github.binarywang.wxpay.service.ProfitSharingService;
import com.github.binarywang.wxpay.service.RedpackService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.*;
import com.github.binarywang.wxpay.util.SignUtils;
import com.github.binarywang.wxpay.util.XmlConfig;
import com.google.common.base.Joiner;
@@ -63,6 +60,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
private EntPayService entPayService = new EntPayServiceImpl(this);
private ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
private RedpackService redpackService = new RedpackServiceImpl(this);
private BusinessCircleService businessCircleService = new BusinessCircleServiceImpl(this);
private MemberCardService memberCardServiceService = new MemberCardServiceImpl(this);
private Applyment4SubService applyment4SubService = new Applyment4SubServiceImpl(this);
private MerchantMediaService merchantMediaService = new MerchantMediaServiceImpl(this);
private BankService bankService = new BankServiceImpl(this);

/**
* The Config.
@@ -79,11 +81,36 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
return profitSharingService;
}

@Override
public BusinessCircleService getBusinessCircleService() {
return this.businessCircleService;
}

@Override
public MemberCardService getMemberCardService(){
return this.memberCardServiceService;
}

@Override
public RedpackService getRedpackService() {
return this.redpackService;
}

@Override
public Applyment4SubService getApplyment4SubService() {
return applyment4SubService;
}

@Override
public MerchantMediaService getMerchantMediaService() {
return merchantMediaService;
}

@Override
public BankService getBankService() {
return bankService;
}

@Override
public void setEntPayService(EntPayService entPayService) {
this.entPayService = entPayService;


+ 125
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BusinessCircleServiceImpl.java ファイルの表示

@@ -0,0 +1,125 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.businesscircle.*;
import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.BusinessCircleService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.AesUtils;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Objects;

/**
* 微信支付-微信支付智慧商圈service
*
* @author thinsstar
*/
@Slf4j
@RequiredArgsConstructor
public class BusinessCircleServiceImpl implements BusinessCircleService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;

@Override
public String notifyPoints(PointsNotifyRequest request) throws WxPayException {
String url = String.format("%s/v3/businesscircle/points/notify", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
return this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}

/**
* 校验通知签名
*
* @param header 通知头信息
* @param data 通知数据
* @return true:校验通过 false:校验不通过
*/
private boolean verifyNotifySign(SignatureHeader header, String data) {
String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
return payService.getConfig().getVerifier().verify(header.getSerialNo(),
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
}

@Override
public BusinessCircleNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
throw new WxPayException("非法请求,头部信息验证失败");
}
return GSON.fromJson(data, BusinessCircleNotifyData.class);
}

@Override
public PaidResult decryptPaidNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
BusinessCircleNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), PaidResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public RefundResult decryptRefundNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
BusinessCircleNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), RefundResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardAuthorizeNotifyResult decryptMemberCardAuthorizeNotifyDataResource(BusinessCircleNotifyData data) throws WxPayException {
BusinessCircleNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), MemberCardAuthorizeNotifyResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardAuthorizeResult getAuthorizations(String openid) throws WxPayException {
String url = String.format("%s/v3/businesscircle/user-authorizations/%s?sub_mchid=%s&appid=%s",
this.payService.getPayBaseUrl(),openid,this.payService.getConfig().getSubMchId(),this.payService.getConfig().getAppId());
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,MemberCardAuthorizeResult.class);
}

@Override
public PointsCommitStatusResult getPointsCommitStatus(String brandid, String openid) throws WxPayException {
String url = String.format("%s/v3/businesscircle/user/%s/points/commit_status?sub_mchid=%s&brandid=%s&appid=%s",
this.payService.getPayBaseUrl(),openid,this.payService.getConfig().getSubMchId(),brandid,this.payService.getConfig().getAppId());
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,PointsCommitStatusResult.class);
}

@Override
public void notifyParkings(ParkingNotifyRequest request) throws WxPayException {
request.setAppid(this.payService.getConfig().getAppId());
request.setSubMchid(this.payService.getConfig().getSubMchId());
String url = String.format("%s/v3/businesscircle/parkings", this.payService.getPayBaseUrl());
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
}
}

+ 87
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MemberCardServiceImpl.java ファイルの表示

@@ -0,0 +1,87 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader;
import com.github.binarywang.wxpay.bean.membercard.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MemberCardService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.AesUtils;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Objects;

/**
* 会员卡相关
*
* @author thinsstar
*/
@Slf4j
@RequiredArgsConstructor
public class MemberCardServiceImpl implements MemberCardService {
private static final Gson GSON = new GsonBuilder().create();
private final WxPayService payService;

/**
* 校验通知签名
*
* @param header 通知头信息
* @param data 通知数据
* @return true:校验通过 false:校验不通过
*/
private boolean verifyNotifySign(SignatureHeader header, String data) {
String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
return payService.getConfig().getVerifier().verify(header.getSerialNo(),
beforeSign.getBytes(StandardCharsets.UTF_8), header.getSigned());
}

@Override
public MemberCardNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
throw new WxPayException("非法请求,头部信息验证失败");
}
return GSON.fromJson(data, MemberCardNotifyData.class);
}

@Override
public MemberCardActivateResult decryptActivateNotifyDataResource(MemberCardNotifyData data) throws WxPayException {
MemberCardNotifyData.Resource resource = data.getResource();
String cipherText = resource.getCipherText();
String associatedData = resource.getAssociatedData();
String nonce = resource.getNonce();
String apiV3Key = this.payService.getConfig().getApiV3Key();
try {
return GSON.fromJson(AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key), MemberCardActivateResult.class);
} catch (GeneralSecurityException | IOException e) {
throw new WxPayException("解析报文异常!", e);
}
}

@Override
public MemberCardResult getMemberCard(String card_id, String code) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s", this.payService.getPayBaseUrl(),card_id,code);
String response = this.payService.getV3WithWechatPaySerial(url);
return GSON.fromJson(response,MemberCardResult.class);
}

@Override
public void updMemberCard(String card_id, String code, MemberCardUpdRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s", this.payService.getPayBaseUrl(),card_id,code);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.patchV3(url, GSON.toJson(request));
}

@Override
public void setMemberCardRights(String card_id, String code, MemberCardRightsRequest request) throws WxPayException {
String url = String.format("%s/v3/marketing/membercard-open/cards/%s/codes/%s/rights", this.payService.getPayBaseUrl(),card_id,code);
RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
this.payService.patchV3(url, GSON.toJson(request));
}

}

+ 60
- 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/MerchantMediaServiceImpl.java ファイルの表示

@@ -0,0 +1,60 @@
package com.github.binarywang.wxpay.service.impl;

import com.github.binarywang.wxpay.bean.media.ImageUploadResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.MerchantMediaService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.WechatPayUploadHttpPost;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.net.URI;

/**
* 微信支付-媒体文件上传service
* @author zhouyongshen
*/
@Slf4j
@RequiredArgsConstructor
public class MerchantMediaServiceImpl implements MerchantMediaService {
private final WxPayService payService;

@Override
public ImageUploadResult imageUploadV3(File imageFile) throws WxPayException,IOException {
String url = String.format("%s/v3/merchant/media/upload", this.payService.getPayBaseUrl());

try (FileInputStream s1 = new FileInputStream(imageFile)) {
String sha256 = DigestUtils.sha256Hex(s1);
try (InputStream s2 = new FileInputStream(imageFile)) {
WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url))
.withImage(imageFile.getName(), sha256, s2)
.build();
String result = this.payService.postV3(url, request);
return ImageUploadResult.fromJson(result);
}
}
}

@Override
public ImageUploadResult imageUploadV3(InputStream inputStream, String fileName) throws WxPayException, IOException {
String url = String.format("%s/v3/merchant/media/upload", this.payService.getPayBaseUrl());
try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[2048];
int len;
while ((len = inputStream.read(buffer)) > -1) {
bos.write(buffer, 0, len);
}
bos.flush();
byte[] data = bos.toByteArray();
String sha256 = DigestUtils.sha256Hex(data);
WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(URI.create(url))
.withImage(fileName, sha256, new ByteArrayInputStream(data))
.build();
String result = this.payService.postV3(url, request);
return ImageUploadResult.fromJson(result);
}
}

}

変更されたファイルが多すぎるため、一部のファイルは表示されません

読み込み中…
キャンセル
保存