├── .gitignore
├── LICENSE.txt
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
└── main
├── java
└── com
│ └── leone
│ └── pay
│ ├── PayApplication.java
│ ├── ali
│ ├── controller
│ │ └── AliPayController.java
│ └── service
│ │ └── AliPayService.java
│ ├── common
│ ├── Result.java
│ ├── config
│ │ ├── AppConfig.java
│ │ └── SwaggerConfig.java
│ ├── enums
│ │ ├── ResultEnum.java
│ │ ├── status
│ │ │ └── OrderStatus.java
│ │ └── type
│ │ │ ├── OrderType.java
│ │ │ └── WxPayType.java
│ ├── exception
│ │ ├── ExceptionMessage.java
│ │ ├── ExceptionResult.java
│ │ ├── GlobalExceptionHandler.java
│ │ └── ValidateException.java
│ └── property
│ │ ├── AliProperties.java
│ │ ├── AppProperties.java
│ │ └── WxProperties.java
│ ├── entity
│ ├── Goods.java
│ ├── Order.java
│ ├── OrderBill.java
│ ├── OrderItem.java
│ └── User.java
│ ├── mapper
│ ├── GoodsMapper.java
│ ├── OrderBillMapper.java
│ ├── OrderItemMapper.java
│ ├── OrderMapper.java
│ └── UserMapper.java
│ ├── service
│ ├── OrderBillService.java
│ ├── OrderService.java
│ └── UserService.java
│ ├── utils
│ ├── HttpUtil.java
│ ├── PaymentUtils.java
│ └── RandomUtil.java
│ └── wx
│ ├── controller
│ └── WxPayController.java
│ ├── pojo
│ └── WxUser.java
│ └── service
│ └── WxPayService.java
└── resources
└── application.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | # maven ignore
2 | target/
3 | *.jar
4 | *.war
5 | *.zip
6 | *.tar
7 | *.tar.gz
8 |
9 | # eclipse ignore
10 | .settings/
11 | .project
12 | .classpath
13 |
14 | # idea ignore
15 | .idea/
16 | *.ipr
17 | *.iml
18 | *.iws
19 |
20 | # temp ignore
21 | *.log
22 | *.cache
23 | *.diff
24 | *.patch
25 | *.tmp
26 |
27 | # system ignore
28 | .DS_Store
29 | Thumbs.db
30 |
31 | # else
32 | .springBeans
33 | out
34 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "{}"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright {yyyy} {name of copyright owner}
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-pay
2 | 基于 Spring Boot 的各种支付对接微信App支付、小程序支付、微信扫码支付、微信退款、支付宝App支付、扫码支付,提现、退款
3 |
4 |
5 | ## 微信支付
6 |
7 | **微信支付流程**
8 |
9 | ### 微信App支付
10 |
11 | **场景介绍**
12 |
13 | 适用于商户在移动端APP中集成微信支付功能。商户APP调用微信提供的SDK调用微信支付模块,商户APP会跳转到微信中完成支付,支付完后跳回到商户APP内,最后展示支付结果。目前微信支付支持手机系统有:IOS(苹果)、Android(安卓)和WP(Windows Phone)。
14 |
15 | **交互细节**
16 |
17 | * 步骤1:用户进入商户APP,选择商品下单、确认购买,进入支付环节。商户服务后台生成支付订单,签名后将数据传输到APP端。
18 |
19 | * 步骤2:用户点击后发起支付操作,进入到微信界面,调起微信支付,出现确认支付界面。
20 |
21 | * 步骤3:用户确认收款方和金额,点击立即支付后出现输入密码界面,可选择零钱或银行卡支付。
22 |
23 | * 第四步:输入正确密码后,支付完成,用户端微信出现支付详情页面。
24 |
25 | * 第五步:回跳到商户APP中,商户APP根据支付结果个性化展示订单处理结果。
26 |
27 | **业务流程图**
28 |
29 | 
30 |
31 |
32 | **商户系统和微信支付系统交互说明**
33 |
34 | * 1.用户在商户APP中选择商品,提交订单,选择微信支付。
35 |
36 | * 2.商户后台收到用户支付单,调用微信支付统一下单接口。
37 |
38 | * 3.统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay
39 |
40 | * 4.商户APP调起微信支付。api参见本章节。
41 |
42 | * 5.商户后台接收支付通知。api参见。
43 |
44 | * 6.商户后台查询支付结果。
45 |
46 |
47 | ### 微信小程序支付
48 |
49 | 小程序支付需要先有个小程序,并且好要有个一商户号,这样才能获取到一些必须要的信息。
50 |
51 | **业务流程**
52 |
53 | 1、小程序内调用登录接口,获取到用户的openid。
54 |
55 | 2、商户server调用支付统一下单。
56 |
57 | 3、商户server调用再次签名。
58 |
59 | 4、商户server接收支付通知,并回复微信收到通知。
60 |
61 | 5、商户server查询支付结果。
62 |
63 | 
64 |
65 |
66 | 小程序支付后App支付流程差不多都是现在后台向微信预下单然后返回调用返回的数据并进行签名前端支付成功后,微信会回调商户的后台服务,商户的后台服务做相应的处理。
67 |
68 |
69 | ### 微信扫码支付
70 |
71 | **场景介绍**
72 |
73 | * 1.商户根据微信支付的规则,为不同商品生成不同的二维码,展示在各种场景,用于用户扫描购买。
74 |
75 | * 2.用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付。
76 |
77 | * 3.用户确认支付,输入支付密码。
78 |
79 | * 4.支付完成后会提示用户支付成功,商户后台得到支付成功的通知,然后进行发货处理。
80 |
81 | **业务流程图**
82 |
83 | 
84 |
85 | **业务刘成刚说明**
86 |
87 | 业务流程说明:
88 |
89 | * 1.商户后台系统根据用户选购的商品生成订单。
90 |
91 | * 2.用户确认支付后调用微信支付【统一下单API】生成预支付交易;
92 |
93 | * 3.微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
94 |
95 | * 4.商户后台系统根据返回的code_url生成二维码。
96 |
97 | * 5.用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
98 |
99 | * 6.微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
100 |
101 | * 7.用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
102 |
103 | * 8.微信支付系统根据用户授权完成支付交易。
104 |
105 | * 9.微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
106 |
107 | * 10.微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
108 |
109 |
110 | ### 微信公众号支付
111 |
112 |
113 | ### 微信退款
114 |
115 | **应用场景**
116 |
117 | 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
118 |
119 | 注意:
120 |
121 | * 1、交易时间超过一年的订单无法提交退款
122 |
123 | * 2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号
124 |
125 | * 3、请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次,错误或无效请求频率限制:6qps,即每秒钟异常或错误的退款申请请求不超过6次
126 |
127 | * 4、每个支付订单的部分退款次数不能超过50次
128 |
129 | * 5、微信退款需要双向证书
130 |
131 |
132 |
133 | ## 支付宝支付
134 |
135 | ### 支付宝App支付
136 |
137 | ### 支付宝扫码支付
138 |
139 | ### 支付宝退款
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ] ; then
38 |
39 | if [ -f /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
支付宝支付
42 | *
43 | * @author leone
44 | * @since 2018-05-27
45 | **/
46 | @Slf4j
47 | @Service
48 | public class AliPayService {
49 |
50 | @Resource
51 | private OrderService orderService;
52 |
53 | @Resource
54 | private UserService userService;
55 |
56 | @Resource
57 | private AppProperties appProperties;
58 |
59 | @Resource
60 | private ObjectMapper objectMapper;
61 |
62 | @Resource
63 | private OrderBillService orderBillService;
64 |
65 | // 阿里 sdk 封装
66 | private AlipayClient alipayClient;
67 |
68 | @PostConstruct
69 | public void initMethod() {
70 | alipayClient = new DefaultAlipayClient(
71 | appProperties.getAli().getServer_url(),
72 | appProperties.getAli().getApp_id(),
73 | appProperties.getAli().getAlipay_private_key(),
74 | appProperties.getAli().getFormat(),
75 | appProperties.getAli().getCharset(),
76 | appProperties.getAli().getAlipay_public_key(),
77 | appProperties.getAli().getSign_type());
78 | }
79 |
80 | /**
81 | * 支付宝提现
82 | *
83 | * @param orderId
84 | */
85 | public Result deposit(Long orderId) {
86 | // 校验订单信息
87 | Order order = orderService.findOne(orderId);
88 | if (order.getStatus() != OrderStatus.CREATE.getStatus()) {
89 | log.error(ExceptionMessage.ORDER_STATUS_INCORRECTNESS + " orderId: {}", orderId);
90 | throw new ValidateException(ExceptionMessage.ORDER_STATUS_INCORRECTNESS);
91 | }
92 |
93 | AlipayFundTransToaccountTransferModel transferModel = new AlipayFundTransToaccountTransferModel();
94 |
95 | transferModel.setOutBizNo(1 + RandomUtil.randomNum(15));
96 | transferModel.setAmount(order.getTotalFee().toString());
97 | transferModel.setPayeeAccount("real account");
98 | transferModel.setPayeeRealName("real name");
99 | transferModel.setPayerShowName("from name");
100 | transferModel.setRemark("remark");
101 | transferModel.setPayeeType("ALIPAY_LOGONID");
102 | try {
103 | AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
104 | request.setBizModel(transferModel);
105 | AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
106 | } catch (AlipayApiException e) {
107 | log.info("ali deposit error message:{}", e.getMessage());
108 | return Result.success(ExceptionMessage.ALI_DEPOSIT_SUCCESS);
109 | }
110 | return Result.error(ExceptionMessage.ALI_DEPOSIT_FAILED);
111 | }
112 |
113 |
114 | /**
115 | * 支付宝扫码支付生成二维码响应到浏览器
116 | *
117 | * @param orderId
118 | * @param response
119 | * @return
120 | */
121 | public Result aliQrCodePay(Long orderId, HttpServletResponse response) throws Exception {
122 | // 校验订单信息
123 | Order order = orderService.findOne(orderId);
124 | if (order.getStatus() != OrderStatus.CREATE.getStatus()) {
125 | log.error(ExceptionMessage.ORDER_STATUS_INCORRECTNESS + " orderId: {}", orderId);
126 | throw new ValidateException(ExceptionMessage.ORDER_STATUS_INCORRECTNESS);
127 | }
128 |
129 | AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
130 | Map
9 | *
10 | * @author leone
11 | **/
12 | public class Result
5 | *
6 | * @author leone
7 | * @since 2019-04-23
8 | **/
9 | public enum OrderType {
10 |
11 | CREATE(0, "微信支付"), PAY(1, "支付宝支付"), DELIVER(2, "银联支付");
12 |
13 | private int status;
14 |
15 | private String payType;
16 |
17 | OrderType() {
18 | }
19 |
20 | OrderType(int status, String payType) {
21 | this.status = status;
22 | this.payType = payType;
23 | }
24 |
25 | public int getStatus() {
26 | return status;
27 | }
28 |
29 | public String getPayType() {
30 | return payType;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/enums/type/WxPayType.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.enums.type;
2 |
3 | /**
4 | *
5 | *
6 | * @author leone
7 | * @since 2019-04-23
8 | **/
9 | public enum WxPayType {
10 |
11 | CREATE(0, "APP"), PAY(1, "NATIVE"), DELIVER(2, "JS_API");
12 |
13 | private int status;
14 |
15 | private String payType;
16 |
17 |
18 | WxPayType(int status, String payType) {
19 | this.status = status;
20 | this.payType = payType;
21 | }
22 |
23 | WxPayType() {
24 | }
25 |
26 | public int getStatus() {
27 | return status;
28 | }
29 |
30 | public String getPayType() {
31 | return payType;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/exception/ExceptionMessage.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.exception;
2 |
3 | /**
4 | * @author leone
5 | **/
6 | public enum ExceptionMessage {
7 |
8 | ERROR(50000, "异常"),
9 | SUCCESS(20000, "成功"),
10 | PERMISSION_DENIED(40001, "权限不足"),
11 | PHONE_LAYOUT_FAIL(40002, "手机号码格式不正确"),
12 | AUTH_TOKEN(40010, "auth.token.wrong"),
13 | AUTH_TOKEN_EMPTY(40011, "auth.token.empty"),
14 | AUTH_ACCOUNT_PASSWORD_WRONG(40012, "账号或密码错误"),
15 | ACCOUNT_HAS_DISABLED(40013, "账号已被禁用"),
16 | AUTH_PERMISSION(40014, "权限不足"),
17 | REQUEST_ARGUMENT(40015, "request.argument"),
18 | INTERNAL_SERVER_ERROR(40016, "server.internal"),
19 | AUTH_CAPTCHA_WRONG(40017, "验证码错误"),
20 | AUTH_CAPTCHA_LOST(40018, "验证码已失效"),
21 | DELETE_IDS_FAIL(40020, "删除的id列表有误"),
22 | DELETE_FAIL(40021, "批量删除失败"),
23 | COLLECT_TYPE_FAIL(40022, "收藏类型错误"),
24 | USER_NOT_EXIST(40019, "user.not.exist"),
25 | CAPTCHA_FAIL(40023, "验证码有误"),
26 | ACTIVITY_ORDER_STATUS_FAIL(40024, "活动订单状态不正确"),
27 | REFUNDS_CANNOT_BE_GREATER_THAN_ORDERS(40025, "退款商品不能大于订单商品数量"),
28 | ORDER_STATUS_FAIL(40027, "订单状态不正确"),
29 | AFTER_SALES_ORDER_ALREADY_EXISTS(40028, "售后订单已存在"),
30 | AVAILABLE_INTEGRAL_DEFICIENCY(40029, "可用积分不足"),
31 | USER_ID_AND_SHOPPING_CART_ID_DO_NOT_MATCH(40030, "用户id和购物车id不匹配"),
32 | THE_SHIPPING_ADDRESS_ALREADY_EXISTS(40031, "用户收货地址已存在"),
33 | WRONG_VALUE_OF_DISCOUNT_COUPONS(40032, "折扣券数值有误"),
34 | INCORRECT_COUPON_STATUS(40033, "优惠券状态有误"),
35 | INVENTORY_SHORTAGE(40034, "商品库存不足"),
36 | ORDER_NOT_EXIST(40035, "订单不存在"),
37 | PAYMENT_FAILURE(40036, "支付失败"),
38 | SIGNATURE_VERIFICATION_FAILED(40037, "签名校验失败"),
39 | WEI_XIN_PAY_FAIL(40038, "微信发起支付失败"),
40 | ACTIVITY_CLOSED(40039, "活动已结束"),
41 | THE_CAMPAIGN_HAS_ALREADY_STARTED(40041, "活动已经开始"),
42 | THE_START_TIME_CANNOT_BE_GREATER_THAN_THE_END_TIME(40041, "开始时间不能大于结束时间"),
43 | THE_START_TIME_CANNOT_BE_LESS_THAN_THE_CURRENT_TIME(40042, "开始时间不能小于当前时间"),
44 | CURRENT_ORDER_IS_NOT_SHIPPED(40043, "当前订单未发货"),
45 | XML_DATA_INCORRECTNESS(40044, "xml数据格式不正确"),
46 | WX_NATIVE_PRE_PAY_FAILED(40045, "微信扫码支付预下单失败"),
47 | WX_REFUND_FAILED(40046, "微信退款失败"),
48 | ALI_DEPOSIT_FAILED(40060, "支付宝提现失败"),
49 | ALI_DEPOSIT_SUCCESS(40061, "支付宝提现成功"),
50 | ALI_PAY_CREATE_QR_CODE_SUCCESS(40062, "支付宝生成二维码成功"),
51 | ALI_PAY_REFUND_FAILED(40063, "支付宝退款失败"),
52 | ORDER_STATUS_INCORRECTNESS(40090, "订单状态不正确")
53 |
54 | ;
55 |
56 |
57 | private Integer code;
58 |
59 | private String message;
60 |
61 | ExceptionMessage(Integer code, String message) {
62 | this.code = code;
63 | this.message = message;
64 | }
65 |
66 | ExceptionMessage() {
67 | }
68 |
69 | public Integer getCode() {
70 | return code;
71 | }
72 |
73 | public void setCode(Integer code) {
74 | this.code = code;
75 | }
76 |
77 | public String getMessage() {
78 | return message;
79 | }
80 |
81 | public void setMessage(String message) {
82 | this.message = message;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/exception/ExceptionResult.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.exception;
2 |
3 | /**
4 | * @author leone
5 | * @since 2018-08-09
6 | **/
7 | public class ExceptionResult {
8 |
9 | private Integer code;
10 |
11 | private String message;
12 |
13 | public ExceptionResult(Integer code) {
14 | this.code = code;
15 | }
16 |
17 | public ExceptionResult(Integer code, String message) {
18 | this.code = code;
19 | this.message = message;
20 | }
21 |
22 | public Integer getCode() {
23 | return code;
24 | }
25 |
26 | public String getMessage() {
27 | return message;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/exception/GlobalExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.exception;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.http.HttpStatus;
6 | import org.springframework.web.bind.MethodArgumentNotValidException;
7 | import org.springframework.web.bind.MissingServletRequestParameterException;
8 | import org.springframework.web.bind.annotation.ExceptionHandler;
9 | import org.springframework.web.bind.annotation.ResponseStatus;
10 | import org.springframework.web.bind.annotation.RestControllerAdvice;
11 |
12 | import javax.security.auth.login.FailedLoginException;
13 |
14 | /**
15 | * @author leone
16 | * @since 2018-08-09
17 | **/
18 | @RestControllerAdvice
19 | public class GlobalExceptionHandler {
20 |
21 | private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
22 |
23 | @ResponseStatus(HttpStatus.BAD_REQUEST)
24 | @ExceptionHandler(ValidateException.class)
25 | public ExceptionResult handleBaseException(ValidateException e) {
26 | logger.error("{}", e.getMessage());
27 | return new ExceptionResult(e.getCode(), e.getMessage());
28 | }
29 |
30 | // @ResponseStatus(HttpStatus.FORBIDDEN)
31 | // @ExceptionHandler(AuthorizationException.class)
32 | // public ExceptionResult handleAuthorizationException(Throwable e) {
33 | // logger.error("{}", e.getMessage());
34 | // return new ExceptionResult(ExceptionMessage.PERMISSION_DENIED.getCode(), ExceptionMessage.PERMISSION_DENIED.getMessage());
35 | // }
36 | //
37 | // @ResponseStatus(HttpStatus.UNAUTHORIZED)
38 | // @ExceptionHandler(AuthenticationException.class)
39 | // public ExceptionResult handleAuthenticationException(Throwable e) {
40 | // logger.error("{}", e.getMessage());
41 | // return new ExceptionResult(40003, e.getMessage());
42 | // }
43 |
44 | @ResponseStatus(HttpStatus.BAD_REQUEST)
45 | @ExceptionHandler(FailedLoginException.class)
46 | public ExceptionResult handleFailedLoginException(FailedLoginException e) {
47 | logger.error("{}", e.getMessage());
48 | return new ExceptionResult(40010, e.getMessage());
49 | }
50 |
51 | @ResponseStatus(HttpStatus.BAD_REQUEST)
52 | @ExceptionHandler(IllegalArgumentException.class)
53 | public ExceptionResult handleBaseException(IllegalArgumentException e) {
54 | logger.error("{}", e.getMessage());
55 | return new ExceptionResult(40000, e.getMessage());
56 | }
57 |
58 | // @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
59 | // @ExceptionHandler(Throwable.class)
60 | // public ExceptionResult handleBaseException(Throwable e) {
61 | // logger.error("{}", e.getMessage());
62 | // return new ExceptionResult(50000, e.getMessage());
63 | // }
64 |
65 | @ResponseStatus(HttpStatus.BAD_REQUEST)
66 | @ExceptionHandler(MethodArgumentNotValidException.class)
67 | public ExceptionResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
68 | logger.error("{}", e.getMessage());
69 | return new ExceptionResult(40007, e.getMessage());
70 | }
71 |
72 | @ResponseStatus(HttpStatus.BAD_REQUEST)
73 | @ExceptionHandler(MissingServletRequestParameterException.class)
74 | public ExceptionResult handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
75 | logger.error("{}", e.getMessage());
76 | return new ExceptionResult(40005, e.getMessage());
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/exception/ValidateException.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.exception;
2 |
3 | /**
4 | * @author leone
5 | * @since 2018-08-03
6 | **/
7 | public class ValidateException extends RuntimeException {
8 |
9 | private Integer code;
10 |
11 | private String message;
12 |
13 | public ValidateException(Integer code, String message) {
14 | super(message);
15 | this.code = code;
16 | this.message = message;
17 | }
18 |
19 | public ValidateException() {
20 | }
21 |
22 | public ValidateException(ExceptionMessage messageEnum) {
23 | this.code = messageEnum.getCode();
24 | this.message = messageEnum.getMessage();
25 | }
26 |
27 | public Integer getCode() {
28 | return code;
29 | }
30 |
31 | @Override
32 | public String getMessage() {
33 | return message;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/property/AliProperties.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.property;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author leone
7 | * @since 2018-06-03
8 | **/
9 | @Data
10 | public class AliProperties {
11 |
12 | /*应用id*/
13 | public String app_id;
14 |
15 | /*商家id*/
16 | private String mch_id;
17 |
18 | /*调用接口的url*/
19 | private String server_url;
20 |
21 | /*应用私钥*/
22 | public String alipay_private_key;
23 |
24 | /*支付宝公钥*/
25 | public String alipay_public_key;
26 |
27 | /*字符编码*/
28 | public String charset;
29 |
30 | /*签名方式*/
31 | public String sign_type ;
32 |
33 | /*数据格式*/
34 | public String format;
35 |
36 | /*支付回调url*/
37 | private String notify_url;
38 |
39 | /*pc支付前台通知*/
40 | private String return_url;
41 |
42 | /*退款url*/
43 | private String refund_url;
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/property/AppProperties.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.property;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.context.annotation.Configuration;
5 |
6 | /**
7 | * @author leone
8 | * @since 2018-07-31
9 | **/
10 | @Configuration
11 | @ConfigurationProperties(prefix = "app.pay")
12 | public class AppProperties {
13 |
14 | private AliProperties ali = new AliProperties();
15 |
16 | private WxProperties wx = new WxProperties();
17 |
18 | public AliProperties getAli() {
19 | return ali;
20 | }
21 |
22 | public void setAli(AliProperties ali) {
23 | this.ali = ali;
24 | }
25 |
26 | public WxProperties getWx() {
27 | return wx;
28 | }
29 |
30 | public void setWx(WxProperties wx) {
31 | this.wx = wx;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/common/property/WxProperties.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.common.property;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author leone
7 | * @since 2018-06-03
8 | **/
9 | @Data
10 | public class WxProperties {
11 |
12 | /*app id*/
13 | private String app_id;
14 |
15 | /*商户id*/
16 | private String mch_id;
17 |
18 | /*app secret*/
19 | private String app_secret;
20 |
21 | /*app key*/
22 | private String app_key;
23 |
24 | /*api key*/
25 | private String api_key;
26 |
27 | /*交易类型*/
28 | private String trade_type;
29 |
30 | /*合作商key*/
31 | private String partner_key;
32 |
33 | /*退款url*/
34 | private String notify_url;
35 |
36 | /*退款通知url*/
37 | private String refund_notify_url;
38 |
39 | /*创建订单url*/
40 | private String create_order_url;
41 |
42 | /*退款url*/
43 | private String refund_url;
44 |
45 | /*授权url*/
46 | private String auth_url;
47 |
48 | /*获取token的url*/
49 | private String token_url;
50 |
51 | /*获取openid的url*/
52 | private String sessionKey_url;
53 |
54 | /*证书路径*/
55 | private String certificate_path;
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/entity/Goods.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.entity;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import lombok.Data;
5 |
6 | import java.util.Date;
7 |
8 | /**
9 | *
10 | *
11 | * @author leone
12 | * @since 2018-08-23
13 | **/
14 | @Data
15 | public class Goods {
16 |
17 | @ApiModelProperty("商品id")
18 | private Long goodsId;
19 |
20 | @ApiModelProperty("分类id")
21 | private Long categoryId;
22 |
23 | @ApiModelProperty("商品名称")
24 | private String goodsName;
25 |
26 | @ApiModelProperty("商品价格 单位分")
27 | private Long goodsPrice;
28 |
29 | @ApiModelProperty("商品条码")
30 | private String goodsBarcode;
31 |
32 | @ApiModelProperty("商品库存")
33 | private Integer goodsInventory;
34 |
35 | @ApiModelProperty("商品描述")
36 | private String description;
37 |
38 | @ApiModelProperty("图片url")
39 | private String goodsPicture;
40 |
41 | @ApiModelProperty("状态")
42 | private Integer status;
43 |
44 | @ApiModelProperty("创建时间")
45 | private Date createTime;
46 |
47 | @ApiModelProperty("修改时间")
48 | private Date updateTime;
49 |
50 | @ApiModelProperty("是否删除")
51 | private boolean deleted;
52 |
53 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/entity/Order.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.entity;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 | import java.util.Date;
7 |
8 | /**
9 | *
10 | *
11 | * @author leone
12 | * @since 2018-10-27
13 | **/
14 | @Data
15 | public class Order implements Serializable {
16 |
17 | private static final long serialVersionUID = -4683295717374444772L;
18 |
19 | private Long orderId;
20 |
21 | private Long userId;
22 |
23 | private String consignee;
24 |
25 | private Integer postFee;
26 |
27 | private Integer totalFee;
28 |
29 | private Byte status;
30 |
31 | private String remark;
32 |
33 | private String outTradeNo;
34 |
35 | private String transactionId;
36 |
37 | private String createIp;
38 |
39 | private Date createTime;
40 |
41 | private Date finishTime;
42 |
43 | private Date payTime;
44 |
45 | private boolean deleted;
46 |
47 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/entity/OrderBill.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.entity;
2 |
3 | import com.leone.pay.common.enums.type.OrderType;
4 | import lombok.Data;
5 |
6 | import java.util.Date;
7 |
8 | /**
9 | *
10 | *
11 | * @author leone
12 | * @since 2019-04-23
13 | **/
14 | @Data
15 | public class OrderBill {
16 |
17 | private Long orderBillId;
18 |
19 | private Long userId;
20 |
21 | private OrderType orderType;
22 |
23 | private Long payAmount;
24 |
25 | private String outTradeNo;
26 |
27 | private Date createTime;
28 |
29 | private Date updateTime;
30 |
31 | private Boolean deleted;
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/entity/OrderItem.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.entity;
2 |
3 | import lombok.Data;
4 |
5 | import java.io.Serializable;
6 | import java.util.Date;
7 |
8 | /**
9 | *
10 | *
11 | * @author leone
12 | * @since 2018-10-23
13 | **/
14 | @Data
15 | public class OrderItem implements Serializable {
16 |
17 | private static final long serialVersionUID = -7529968762980756395L;
18 |
19 | private String orderItemId;
20 |
21 | private String orderId;
22 |
23 | private String goodsId;
24 |
25 | private String goodsName;
26 |
27 | private Long goodsPrice;
28 |
29 | private Integer goodsCount;
30 |
31 | private String goodsPicture;
32 |
33 | private Date createTime;
34 |
35 | private Date updateTime;
36 |
37 | private Boolean deleted;
38 |
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/entity/User.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.entity;
2 |
3 | import java.io.Serializable;
4 | import java.util.Date;
5 |
6 | /**
7 | * @author leone
8 | * @since 2018-10-23
9 | **/
10 | public class User implements Serializable {
11 |
12 | private static final long serialVersionUID = -2694291552469030037L;
13 | private Long userId;
14 |
15 | private String account;
16 |
17 | private String password;
18 |
19 | private String description;
20 |
21 | private Integer age;
22 |
23 | private String openid;
24 |
25 | private Date createTime;
26 |
27 | private boolean deleted;
28 |
29 | public User() {
30 | }
31 |
32 | public User(String account, String password, String description, Integer age, Date createTime, Boolean deleted) {
33 | this.account = account;
34 | this.password = password;
35 | this.description = description;
36 | this.age = age;
37 | this.createTime = createTime;
38 | this.deleted = deleted;
39 | }
40 |
41 | public User(Long userId, String account, String password, String description, Integer age, Date createTime, Boolean deleted) {
42 | this.userId = userId;
43 | this.account = account;
44 | this.password = password;
45 | this.description = description;
46 | this.age = age;
47 | this.createTime = createTime;
48 | this.deleted = deleted;
49 | }
50 |
51 | public Long getUserId() {
52 | return userId;
53 | }
54 |
55 | public void setUserId(Long userId) {
56 | this.userId = userId;
57 | }
58 |
59 | public String getAccount() {
60 | return account;
61 | }
62 |
63 | public void setAccount(String account) {
64 | this.account = account;
65 | }
66 |
67 | public String getPassword() {
68 | return password;
69 | }
70 |
71 | public void setPassword(String password) {
72 | this.password = password;
73 | }
74 |
75 | public String getDescription() {
76 | return description;
77 | }
78 |
79 | public void setDescription(String description) {
80 | this.description = description;
81 | }
82 |
83 | public Integer getAge() {
84 | return age;
85 | }
86 |
87 | public void setAge(Integer age) {
88 | this.age = age;
89 | }
90 |
91 | public Date getCreateTime() {
92 | return createTime;
93 | }
94 |
95 | public void setCreateTime(Date createTime) {
96 | this.createTime = createTime;
97 | }
98 |
99 | public boolean isDeleted() {
100 | return deleted;
101 | }
102 |
103 | public void setDeleted(boolean deleted) {
104 | this.deleted = deleted;
105 | }
106 |
107 | public String getOpenid() {
108 | return openid;
109 | }
110 |
111 | public void setOpenid(String openid) {
112 | this.openid = openid;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/mapper/GoodsMapper.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.mapper;
2 |
3 | import com.leone.pay.entity.Goods;
4 | import org.mapstruct.Mapper;
5 |
6 | /**
7 | *
8 | *
9 | * @author leone
10 | * @since 2019-04-23
11 | **/
12 | @Mapper
13 | public interface GoodsMapper {
14 |
15 | int deleteByPrimaryKey(Long id);
16 |
17 | int insert(Goods record);
18 |
19 | int insertSelective(Goods record);
20 |
21 | Goods selectByPrimaryKey(Long id);
22 |
23 | int updateByPrimaryKeySelective(Goods record);
24 |
25 | int updateByPrimaryKey(Goods record);
26 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/mapper/OrderBillMapper.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.mapper;
2 |
3 |
4 | import com.leone.pay.entity.OrderBill;
5 | import org.apache.ibatis.annotations.Insert;
6 | import org.apache.ibatis.annotations.Param;
7 | import org.mapstruct.Mapper;
8 |
9 | /**
10 | *
11 | *
12 | * @author leone
13 | * @since 2019-04-23
14 | **/
15 | @Mapper
16 | public interface OrderBillMapper {
17 |
18 | @Insert("insert into t_order_bill() values()")
19 | int save(@Param("bill") OrderBill orderBill);
20 |
21 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/mapper/OrderItemMapper.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.mapper;
2 |
3 | import com.leone.pay.entity.OrderItem;
4 | import org.mapstruct.Mapper;
5 |
6 | /**
7 | *
8 | *
9 | * @author leone
10 | * @since 2019-04-23
11 | **/
12 | @Mapper
13 | public interface OrderItemMapper {
14 |
15 | int deleteByPrimaryKey(String id);
16 |
17 | int insert(OrderItem record);
18 |
19 | int insertSelective(OrderItem record);
20 |
21 | OrderItem selectByPrimaryKey(String id);
22 |
23 | int updateByPrimaryKeySelective(OrderItem record);
24 |
25 | int updateByPrimaryKey(OrderItem record);
26 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/mapper/OrderMapper.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.mapper;
2 |
3 | import com.leone.pay.entity.Order;
4 | import org.apache.ibatis.annotations.Mapper;
5 | import org.apache.ibatis.annotations.Param;
6 | import org.apache.ibatis.annotations.Select;
7 |
8 | /**
9 | *
10 | *
11 | * @author leone
12 | * @since 2019-04-23
13 | **/
14 | @Mapper
15 | public interface OrderMapper {
16 |
17 | int deleteByPrimaryKey(Long id);
18 |
19 | int insert(Order record);
20 |
21 | int insertSelective(Order record);
22 |
23 | Order selectByPrimaryKey(Long id);
24 |
25 | @Select("select * from t_order where orderId = #{orderId}")
26 | Order findByOrderId(@Param("orderId") Long orderId);
27 |
28 | int updateByPrimaryKeySelective(Order record);
29 |
30 | int updateByPrimaryKey(Order record);
31 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.mapper;
2 |
3 | import com.leone.pay.entity.User;
4 | import org.apache.ibatis.annotations.Mapper;
5 |
6 | /**
7 | *
8 | *
9 | * @author leone
10 | * @since 2019-04-23
11 | **/
12 | @Mapper
13 | public interface UserMapper {
14 |
15 | int deleteByPrimaryKey(Long id);
16 |
17 | int insert(User record);
18 |
19 | int insertSelective(User record);
20 |
21 | User findByUserId(Long id);
22 |
23 | int updateByPrimaryKeySelective(User record);
24 |
25 | int updateByPrimaryKey(User record);
26 |
27 | }
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/service/OrderBillService.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.service;
2 |
3 | import com.leone.pay.entity.OrderBill;
4 | import com.leone.pay.mapper.OrderBillMapper;
5 | import org.springframework.stereotype.Service;
6 |
7 | import javax.annotation.Resource;
8 |
9 | /**
10 | *
11 | *
12 | * @author leone
13 | * @since 2019-04-23
14 | **/
15 | @Service
16 | public class OrderBillService {
17 |
18 | @Resource
19 | private OrderBillMapper orderBillMapper;
20 |
21 | /**
22 | * 保存订单流水
23 | * @param orderBill
24 | * @return
25 | */
26 | public int save(OrderBill orderBill) {
27 | return orderBillMapper.save(orderBill);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/service/OrderService.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.service;
2 |
3 | import com.leone.pay.common.exception.ExceptionMessage;
4 | import com.leone.pay.entity.Order;
5 | import com.leone.pay.mapper.OrderMapper;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.util.Assert;
9 |
10 | import javax.annotation.Resource;
11 |
12 | /**
13 | * @author leone
14 | * @since 2018-06-03
15 | **/
16 | @Slf4j
17 | @Service
18 | public class OrderService {
19 |
20 | @Resource
21 | private OrderMapper orderMapper;
22 |
23 | /**
24 | * 查找订单
25 | *
26 | * @param orderId
27 | * @return
28 | */
29 | public Order findOne(Long orderId) {
30 | Order order = orderMapper.findByOrderId(orderId);
31 | Assert.notNull(order, ExceptionMessage.ORDER_NOT_EXIST.getMessage());
32 | return order;
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.service;
2 |
3 | import com.leone.pay.common.exception.ExceptionMessage;
4 | import com.leone.pay.entity.User;
5 | import com.leone.pay.mapper.UserMapper;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.util.Assert;
9 |
10 | import javax.annotation.Resource;
11 |
12 | /**
13 | * @author leone
14 | * @since 2018-06-03
15 | **/
16 | @Slf4j
17 | @Service
18 | public class UserService {
19 |
20 | @Resource
21 | private UserMapper userMapper;
22 |
23 | /**
24 | *
25 | * @param userId
26 | * @return
27 | */
28 | public User findOne(Long userId) {
29 | User user = userMapper.findByUserId(userId);
30 | Assert.notNull(user, ExceptionMessage.USER_NOT_EXIST.getMessage());
31 | return user;
32 | }
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/leone/pay/utils/HttpUtil.java:
--------------------------------------------------------------------------------
1 | package com.leone.pay.utils;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.apache.http.*;
5 | import org.apache.http.client.HttpRequestRetryHandler;
6 | import org.apache.http.client.config.RequestConfig;
7 | import org.apache.http.client.methods.HttpGet;
8 | import org.apache.http.client.methods.HttpPost;
9 | import org.apache.http.client.utils.URIBuilder;
10 | import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
11 | import org.apache.http.entity.StringEntity;
12 | import org.apache.http.impl.client.CloseableHttpClient;
13 | import org.apache.http.impl.client.HttpClients;
14 | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
15 | import org.apache.http.message.BasicNameValuePair;
16 | import org.apache.http.protocol.HttpContext;
17 | import org.apache.http.ssl.SSLContexts;
18 | import org.apache.http.util.EntityUtils;
19 |
20 | import javax.net.ssl.SSLContext;
21 | import java.io.File;
22 | import java.io.FileInputStream;
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.net.SocketException;
26 | import java.nio.charset.StandardCharsets;
27 | import java.security.KeyStore;
28 | import java.util.ArrayList;
29 | import java.util.List;
30 | import java.util.Map;
31 |
32 | /**
33 | * http请求工具类
34 | *
35 | * @author leone
36 | **/
37 | @Slf4j
38 | public class HttpUtil {
39 |
40 | private HttpUtil() {
41 | }
42 |
43 | private final static String UTF8 = StandardCharsets.UTF_8.displayName();
44 |
45 | private static CloseableHttpClient httpClient;
46 |
47 | static {
48 | RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(1000).setSocketTimeout(4000).setExpectContinueEnabled(true).build();
49 | PoolingHttpClientConnectionManager pool = new PoolingHttpClientConnectionManager();
50 | pool.setMaxTotal(300);
51 | pool.setDefaultMaxPerRoute(50);
52 | HttpRequestRetryHandler retryHandler = (IOException exception, int executionCount, HttpContext context) -> {
53 | if (executionCount > 1) {
54 | return false;
55 | }
56 | if (exception instanceof NoHttpResponseException) {
57 | log.info("[NoHttpResponseException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
58 | return true;
59 | } else if (exception instanceof SocketException) {
60 | log.info("[SocketException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
61 | return true;
62 | }
63 | return false;
64 | };
65 | httpClient = HttpClients.custom().setConnectionManager(pool).setDefaultRequestConfig(requestConfig).setRetryHandler(retryHandler).build();
66 | }
67 |
68 | /**
69 | * @param certPath
70 | * @param password
71 | * @return
72 | * @throws Exception
73 | */
74 | public static CloseableHttpClient sslHttpsClient(String certPath, String password) throws Exception {
75 | KeyStore keyStore = KeyStore.getInstance("PKCS12");
76 | try (InputStream inputStream = new FileInputStream(new File(certPath))) {
77 | keyStore.load(inputStream, password.toCharArray());
78 | }
79 | SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();
80 | SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
81 | return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
82 | }
83 |
84 |
85 | /**
86 | * 设置请求头信息
87 | *
88 | * @param headers
89 | * @param request
90 | * @return
91 | */
92 | private static void setHeaders(Map
37 | *
38 | * @author leone
39 | * @since 2019-04-23
40 | **/
41 | @Slf4j
42 | public class PaymentUtils {
43 |
44 | private PaymentUtils() {
45 | }
46 |
47 | /**
48 | * 读取 request 中的数据
49 | *
50 | * @param request
51 | * @return
52 | */
53 | public static String getRequestData(HttpServletRequest request) {
54 | StringBuilder sb = new StringBuilder();
55 | BufferedReader br = null;
56 | String line;
57 | try {
58 | // 接收request数据流,并指定编码格式接收
59 | br = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8));
60 | while ((line = br.readLine()) != null) {
61 | sb.append(line);
62 | }
63 | } catch (IOException e) {
64 | e.printStackTrace();
65 | } finally {
66 | if (br != null) {
67 | try {
68 | br.close();
69 | } catch (IOException e) {
70 | e.printStackTrace();
71 | }
72 | }
73 | }
74 | return sb.toString();
75 | }
76 |
77 |
78 | /**
79 | * 加密url
80 | *
81 | * @param value
82 | * @return
83 | */
84 | public static String urlEncoder(String value) {
85 | try {
86 | return URLEncoder.encode(value, StandardCharsets.UTF_8.displayName());
87 | } catch (UnsupportedEncodingException e) {
88 | e.printStackTrace();
89 | }
90 | return null;
91 | }
92 |
93 | /**
94 | * 解码url
95 | *
96 | * @param value
97 | * @return
98 | */
99 | public static String urlDecoder(String value) {
100 | try {
101 | return URLDecoder.decode(value, StandardCharsets.UTF_8.displayName());
102 | } catch (UnsupportedEncodingException e) {
103 | e.printStackTrace();
104 | }
105 | return null;
106 | }
107 |
108 | /**
109 | * 校验手机号
110 | *
111 | * @param phone
112 | * @return
113 | */
114 | public static boolean isMobile(String phone) {
115 | Pattern pattern = Pattern.compile("^[1][3,4,5,7,8,9][0-9]{9}$");
116 | Matcher matcher = pattern.matcher(phone);
117 | return matcher.matches();
118 | }
119 |
120 | /**
121 | * 匹配ip是否合法
122 | *
123 | * @param ip
124 | * @return
125 | */
126 | public static Boolean isIp(String ip) {
127 | String re = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
128 | Pattern pattern = Pattern.compile(re);
129 | Matcher matcher = pattern.matcher(ip);
130 | return matcher.matches();
131 | }
132 |
133 |
134 | /**
135 | * 支付参数生成签名
136 | *
137 | * @param params
138 | * @param apiKey
139 | * @return
140 | */
141 | public static String sign(Map
142 | * 收到微信通知后应返回微信已经收到通知,不然微信会回调多次 可能会出现保存多次订单流水的现象
143 | *
144 | * 返回给微信通知示例如下
145 | *
146 | *