├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── github │ └── actar233 │ └── mbdpay │ ├── Constant.java │ ├── MbdPayClient.java │ ├── QueryStringBuilder.java │ ├── exception │ └── MbdPayException.java │ ├── model │ ├── AliPayParams.java │ ├── AliPayResult.java │ ├── RefundParams.java │ ├── RefundResult.java │ ├── Result.java │ ├── SearchOrderParams.java │ ├── SearchOrderResult.java │ ├── WxH5Params.java │ ├── WxH5Result.java │ ├── WxJsApiParams.java │ └── WxJsApiResult.java │ └── notice │ ├── Notice.java │ ├── NoticeData.java │ ├── NoticeDataChargeSucceeded.java │ ├── NoticeDataComplaint.java │ └── NoticeType.java └── test └── java └── com └── github └── actar233 └── mbdpay └── ClientTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | target 4 | *.iml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 taohua 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 面包多支付Java版本SDK 2 | 3 | [![](https://www.jitpack.io/v/actar233/mbdpay-java.svg)](https://www.jitpack.io/#actar233/mbdpay-java) 4 | 5 | # 如何使用 6 | 7 | 1. 引入jetpack仓库 8 | 9 | maven 10 | ```xml 11 | 12 | 13 | jitpack.io 14 | https://www.jitpack.io 15 | 16 | 17 | ``` 18 | 19 | gradle 20 | ```groovy 21 | allprojects { 22 | repositories { 23 | ... 24 | maven { url 'https://www.jitpack.io' } 25 | } 26 | } 27 | ``` 28 | 29 | 2. 引入SDK 30 | 31 | maven 32 | ```xml 33 | 34 | com.github.actar233 35 | mbdpay-java 36 | 1.0.2 37 | 38 | ``` 39 | 40 | gradle 41 | ```groovy 42 | dependencies { 43 | implementation 'com.github.actar233:mbdpay-java:1.0.2' 44 | } 45 | ``` 46 | 47 | 3. 初始化 48 | ```java 49 | MbdPayClient client = new MbdPayClient("", ""); 50 | ``` 51 | 52 | 4. 获取微信用户openid 53 | ```java 54 | private static void openid(MbdPayClient client){ 55 | System.out.println(client.openid("https://www.baidu.com")); 56 | } 57 | ``` 58 | 59 | 5. 支付 60 | ```java 61 | // 支付宝 62 | private static void aliPay(MbdPayClient client) { 63 | try { 64 | AliPayResult result = client.aliPay(AliPayParams.builder() 65 | .url("") 66 | .amountTotal(1) 67 | .callbackUrl("") 68 | .description("") 69 | .outTradeNo("<可选:outTradeNo>") 70 | .build()); 71 | if (result.isSuccess()) { 72 | System.out.println("查询成功"); 73 | System.out.println(result); 74 | } else { 75 | System.out.println("查询失败"); 76 | System.out.println(result.getError()); 77 | } 78 | } catch (MbdPayException e) { 79 | System.out.println("请求异常"); 80 | e.printStackTrace(); 81 | } 82 | } 83 | // 微信H5 84 | private static void wxH5(MbdPayClient client) { 85 | try { 86 | WxH5Result result = client.wxH5(WxH5Params.builder() 87 | .amountTotal(1) 88 | .description("") 89 | .channel("h5") 90 | .outTradeNo("<可选:outTradeNo>") 91 | .build()); 92 | if (result.isSuccess()) { 93 | System.out.println("查询成功"); 94 | System.out.println(result); 95 | } else { 96 | System.out.println("查询失败"); 97 | System.out.println(result.getError()); 98 | } 99 | } catch (MbdPayException e) { 100 | System.out.println("请求异常"); 101 | e.printStackTrace(); 102 | } 103 | } 104 | // 微信JSAPI 105 | private static void wxJsApi(MbdPayClient client) { 106 | try { 107 | WxJsApiResult result = client.wxJsApi(WxJsApiParams.builder() 108 | .openid("") 109 | .amountTotal(1) 110 | .callbackUrl("") 111 | .description("") 112 | .outTradeNo("<可选:outTradeNo>") 113 | .build()); 114 | if (result.isSuccess()) { 115 | System.out.println("查询成功"); 116 | System.out.println(result); 117 | // 获取支付参数 118 | System.out.println(result.getPayParams()); 119 | } else { 120 | System.out.println("查询失败"); 121 | System.out.println(result.getError()); 122 | } 123 | } catch (MbdPayException e) { 124 | System.out.println("请求异常"); 125 | e.printStackTrace(); 126 | } 127 | } 128 | ``` 129 | 130 | 6. 查单 131 | ```java 132 | private static void searchOrder(MbdPayClient client) { 133 | try { 134 | SearchOrderResult result = client.searchOrder(SearchOrderParams.builder() 135 | .outTradeNo("") 136 | .build()); 137 | if (result.isSuccess()) { 138 | System.out.println("查询成功"); 139 | System.out.println(result); 140 | } else { 141 | System.out.println("查询失败"); 142 | System.out.println(result.getError()); 143 | } 144 | } catch (MbdPayException e) { 145 | System.out.println("请求异常"); 146 | e.printStackTrace(); 147 | } 148 | } 149 | ``` 150 | 151 | 7. 退款 152 | ```java 153 | private static void refund(MbdPayClient client) { 154 | try { 155 | RefundResult result = client.refund(RefundParams.builder() 156 | .orderId("") 157 | .build()); 158 | if (result.isSuccess()) { 159 | System.out.println("查询成功"); 160 | System.out.println(result); 161 | } else { 162 | System.out.println("查询失败"); 163 | System.out.println(result.getError()); 164 | } 165 | } catch (MbdPayException e) { 166 | System.out.println("请求异常"); 167 | e.printStackTrace(); 168 | } 169 | } 170 | ``` 171 | 172 | 8. 解析通知 173 | ```java 174 | @PostMapping("/callback") 175 | public String callback(@RequestBody String json) throws MbdPayException { 176 | Notice notice = mbdPayClient.parseNotice(json); 177 | System.out.println(notice); 178 | switch (notice.getType()) { 179 | case charge_succeeded: 180 | NoticeDataChargeSucceeded data_cs = (NoticeDataChargeSucceeded) notice.getData(); 181 | System.out.println("支付成功"); 182 | System.out.println("订单号:" + data_cs.getOutTradeNo()); 183 | break; 184 | case complaint: 185 | NoticeDataComplaint data_c = (NoticeDataComplaint) notice.getData(); 186 | System.out.println("投诉成功"); 187 | System.out.println("订单号:" + data_c.getOutTradeNo()); 188 | break; 189 | } 190 | return "success"; 191 | } 192 | ``` 193 | 194 | # 链接 195 | [面包多支付](https://mbd.pub/) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.actar233 8 | mbdpay-java 9 | 1.0.2 10 | 11 | 12 | 13 | 14 | org.apache.maven.plugins 15 | maven-compiler-plugin 16 | 17 | 8 18 | 8 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | org.projectlombok 27 | lombok 28 | 1.18.20 29 | provided 30 | 31 | 32 | com.google.code.gson 33 | gson 34 | 2.8.5 35 | 36 | 37 | com.squareup.okhttp3 38 | okhttp 39 | 3.14.9 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/Constant.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay; 2 | 3 | public class Constant { 4 | /** 5 | * 基础地址 6 | */ 7 | public static final String BASE_URL = "https://api.niucodata.com"; 8 | /** 9 | * openid 10 | */ 11 | public static final String OPENID = "https://p.mbd.pub/openid"; 12 | 13 | /** 14 | * 微信JSAPI 15 | */ 16 | public static final String WX_JSAPI = BASE_URL + "/release/wx/prepay"; 17 | 18 | /** 19 | * 微信H5 20 | */ 21 | public static final String WX_H5 = BASE_URL + "/release/wx/prepay"; 22 | 23 | /** 24 | * 支付宝pay 25 | */ 26 | public static final String ALI_PAY = BASE_URL + "/release/alipay/pay"; 27 | 28 | /** 29 | * 退款 30 | */ 31 | public static final String REFUND = BASE_URL + "/release/main/refund"; 32 | 33 | /** 34 | * 订单查询 35 | */ 36 | public static final String SEARCH_ORDER = BASE_URL + "/release/main/search_order"; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/MbdPayClient.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay; 2 | 3 | import com.github.actar233.mbdpay.exception.MbdPayException; 4 | import com.github.actar233.mbdpay.model.*; 5 | import com.github.actar233.mbdpay.notice.*; 6 | import com.google.gson.Gson; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonObject; 9 | import com.google.gson.JsonParser; 10 | import okhttp3.*; 11 | 12 | import java.io.IOException; 13 | import java.nio.charset.StandardCharsets; 14 | import java.security.MessageDigest; 15 | import java.security.NoSuchAlgorithmException; 16 | import java.util.HashMap; 17 | import java.util.Map; 18 | 19 | public class MbdPayClient { 20 | 21 | private final Gson gson; 22 | private final OkHttpClient okHttpClient; 23 | 24 | /** 25 | * app_id 26 | */ 27 | private final String appId; 28 | 29 | /** 30 | * app_key 31 | */ 32 | private final String appKey; 33 | 34 | public MbdPayClient(String appId, String appKey) { 35 | this.appId = appId; 36 | this.appKey = appKey; 37 | this.gson = new Gson(); 38 | this.okHttpClient = new OkHttpClient().newBuilder().build(); 39 | } 40 | 41 | public RSP post(String url, REQ request, Class clazz) throws MbdPayException { 42 | try { 43 | Map params = params(request); 44 | params.put("app_id", this.appId); 45 | String sign = sign(params); 46 | params.put("sign", sign); 47 | 48 | String json = gson.toJson(params); 49 | 50 | MediaType mediaType = MediaType.parse("application/json;charset=utf-8"); 51 | 52 | RequestBody requestBody = RequestBody.create(mediaType, json); 53 | 54 | Request req = new Request.Builder() 55 | .url(url) 56 | .method("POST", requestBody) 57 | .build(); 58 | 59 | Response rsp = okHttpClient.newCall(req).execute(); 60 | if (rsp.code() != 200) { 61 | throw new MbdPayException(String.format("请求失败,响应码: %d", rsp.code())); 62 | } 63 | 64 | ResponseBody responseBody = rsp.body(); 65 | if (responseBody == null) { 66 | throw new MbdPayException("请求失败"); 67 | } 68 | 69 | return gson.fromJson(responseBody.string(), clazz); 70 | } catch (IOException | MbdPayException e) { 71 | if (e instanceof MbdPayException) { 72 | throw (MbdPayException) e; 73 | } 74 | throw new MbdPayException(e); 75 | } 76 | } 77 | 78 | private Map params(Object src) { 79 | JsonElement tree = gson.toJsonTree(src); 80 | JsonObject object = tree.getAsJsonObject(); 81 | HashMap map = new HashMap<>(); 82 | for (String key : object.keySet()) { 83 | String value = object.get(key).getAsString(); 84 | map.put(key, value); 85 | } 86 | return map; 87 | } 88 | 89 | private String sign(Map map) throws MbdPayException { 90 | QueryStringBuilder builder = QueryStringBuilder.create(); 91 | for (String key : map.keySet()) { 92 | String value = map.get(key); 93 | builder.put(key, value); 94 | } 95 | String signString = String.format("%s&key=%s", builder.build(), this.appKey); 96 | return md5(signString); 97 | } 98 | 99 | public static String md5(String src) throws MbdPayException { 100 | try { 101 | MessageDigest digest = MessageDigest.getInstance("MD5"); 102 | digest.update(src.getBytes(StandardCharsets.UTF_8)); 103 | StringBuilder builder = new StringBuilder(); 104 | for (byte b : digest.digest()) { 105 | builder.append(Integer.toHexString((0x000000FF & b) | 0xFFFFFF00).substring(6)); 106 | } 107 | return builder.toString(); 108 | } catch (NoSuchAlgorithmException e) { 109 | throw new MbdPayException(e); 110 | } 111 | } 112 | 113 | /** 114 | * openid 115 | * 116 | * @param target_url 目标url 117 | * @return url 118 | */ 119 | public String openid(String target_url) { 120 | String qs = QueryStringBuilder.create() 121 | .put("target_url", target_url) 122 | .put("app_id", this.appId) 123 | .build(); 124 | return String.format("%s?%s", Constant.OPENID, qs); 125 | } 126 | 127 | /** 128 | * 微信JSAPI支付 129 | * 130 | * @param params 参数 131 | * @return 结果 132 | * @throws MbdPayException 异常 133 | */ 134 | public WxJsApiResult wxJsApi(WxJsApiParams params) throws MbdPayException { 135 | return post(Constant.WX_JSAPI, params, WxJsApiResult.class); 136 | } 137 | 138 | /** 139 | * 微信H5支付 140 | * 141 | * @param params 参数 142 | * @return 结果 143 | * @throws MbdPayException 异常 144 | */ 145 | public WxH5Result wxH5(WxH5Params params) throws MbdPayException { 146 | return post(Constant.WX_H5, params, WxH5Result.class); 147 | } 148 | 149 | /** 150 | * 支付宝支付 151 | * 152 | * @param params 参数 153 | * @return 结果 154 | * @throws MbdPayException 异常 155 | */ 156 | public AliPayResult aliPay(AliPayParams params) throws MbdPayException { 157 | return post(Constant.ALI_PAY, params, AliPayResult.class); 158 | } 159 | 160 | /** 161 | * 退款 162 | * 163 | * @param params 参数 164 | * @return 结果 165 | * @throws MbdPayException 异常 166 | */ 167 | public RefundResult refund(RefundParams params) throws MbdPayException { 168 | return post(Constant.REFUND, params, RefundResult.class); 169 | } 170 | 171 | /** 172 | * 订单查询 173 | * 174 | * @param params 参数 175 | * @return 结果 176 | * @throws MbdPayException 异常 177 | */ 178 | public SearchOrderResult searchOrder(SearchOrderParams params) throws MbdPayException { 179 | return post(Constant.SEARCH_ORDER, params, SearchOrderResult.class); 180 | } 181 | 182 | /** 183 | * 解析通知 184 | * 185 | * @param json json字符串 186 | * @return 通知 187 | */ 188 | @SuppressWarnings("DuplicatedCode") 189 | public Notice parseNotice(String json) throws MbdPayException { 190 | JsonObject object = new JsonParser().parse(json).getAsJsonObject(); 191 | NoticeType type = NoticeType.valueOf(object.get("type").getAsString()); 192 | Class clazz; 193 | switch (type) { 194 | case charge_succeeded: 195 | clazz = NoticeDataChargeSucceeded.class; 196 | break; 197 | case complaint: 198 | clazz = NoticeDataComplaint.class; 199 | break; 200 | default: 201 | throw new MbdPayException("未知的type类型"); 202 | } 203 | JsonElement objData = object.get("data"); 204 | if (!objData.isJsonObject()) { 205 | throw new MbdPayException("data类型错误"); 206 | } 207 | return Notice.builder() 208 | .type(type) 209 | .data(gson.fromJson(objData.getAsJsonObject(), clazz)) 210 | .build(); 211 | } 212 | 213 | @SuppressWarnings("DuplicatedCode") 214 | public Notice parseNotice(Map map) throws MbdPayException { 215 | Object objType = map.get("type"); 216 | if (!(objType instanceof String)) { 217 | throw new MbdPayException("未知的type类型"); 218 | } 219 | NoticeType type = NoticeType.valueOf((String) objType); 220 | Class clazz; 221 | switch (type) { 222 | case charge_succeeded: 223 | clazz = NoticeDataChargeSucceeded.class; 224 | break; 225 | case complaint: 226 | clazz = NoticeDataComplaint.class; 227 | break; 228 | default: 229 | throw new MbdPayException("未知的type类型"); 230 | } 231 | JsonElement objData = gson.toJsonTree(map.get("data")); 232 | if (!objData.isJsonObject()) { 233 | throw new MbdPayException("data类型错误"); 234 | } 235 | return Notice.builder() 236 | .type(type) 237 | .data(gson.fromJson(objData.getAsJsonObject(), clazz)) 238 | .build(); 239 | } 240 | 241 | } 242 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/QueryStringBuilder.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay; 2 | 3 | import java.util.*; 4 | 5 | public class QueryStringBuilder { 6 | 7 | private final Map> builder; 8 | 9 | public static QueryStringBuilder create() { 10 | return new QueryStringBuilder(); 11 | } 12 | 13 | private QueryStringBuilder() { 14 | this.builder = new HashMap<>(); 15 | } 16 | 17 | public QueryStringBuilder put(String key, String... values) { 18 | List list = this.builder.get(key); 19 | if (list == null) { 20 | list = new ArrayList<>(); 21 | } 22 | list.addAll(Arrays.asList(values)); 23 | this.builder.put(key, list); 24 | return this; 25 | } 26 | 27 | public QueryStringBuilder put(String key, String value) { 28 | List list = this.builder.get(key); 29 | if (list == null) { 30 | list = new ArrayList<>(); 31 | } 32 | list.add(value); 33 | this.builder.put(key, list); 34 | return this; 35 | } 36 | 37 | public String build() { 38 | StringBuilder builder = new StringBuilder(); 39 | String[] keys = this.builder.keySet() 40 | .stream() 41 | .sorted() 42 | .toArray(String[]::new); 43 | for (String key : keys) { 44 | List values = this.builder.get(key); 45 | for (String value : values) { 46 | if (builder.length() > 0) { 47 | builder.append('&'); 48 | } 49 | builder.append(key); 50 | builder.append('='); 51 | builder.append(value); 52 | } 53 | } 54 | return builder.toString(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/exception/MbdPayException.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.exception; 2 | 3 | public class MbdPayException extends Exception { 4 | 5 | public MbdPayException() { 6 | } 7 | 8 | public MbdPayException(String message) { 9 | super(message); 10 | } 11 | 12 | public MbdPayException(String message, Throwable cause) { 13 | super(message, cause); 14 | } 15 | 16 | public MbdPayException(Throwable cause) { 17 | super(cause); 18 | } 19 | 20 | public MbdPayException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 21 | super(message, cause, enableSuppression, writableStackTrace); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/AliPayParams.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class AliPayParams { 14 | 15 | /** 16 | * 必选 是 17 | * 类型 string 18 | * 说明 支付后跳转的URL地址 19 | */ 20 | @SerializedName("url") 21 | private String url; 22 | 23 | /** 24 | * 必选 是 25 | * 类型 string 26 | * 说明 支付描述,一般为商品名称 27 | */ 28 | @SerializedName("description") 29 | private String description; 30 | 31 | /** 32 | * 必选 是 33 | * 类型 number 34 | * 说明 金额,单位为分 35 | */ 36 | @SerializedName("amount_total") 37 | private int amountTotal; 38 | 39 | /** 40 | * 必选 否 41 | * 类型 string 42 | * 说明 订单号,如不填,面包多将随机生成订单号 43 | */ 44 | @SerializedName("out_trade_no") 45 | private String outTradeNo; 46 | 47 | /** 48 | * 必选 否 49 | * 类型 string 50 | * 说明 支付后跳转地址,如不填会只显示「支付成功」 51 | */ 52 | @SerializedName("callback_url") 53 | private String callbackUrl; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/AliPayResult.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | 9 | @EqualsAndHashCode(callSuper = true) 10 | @Data 11 | @ToString(callSuper = true) 12 | @NoArgsConstructor 13 | public class AliPayResult extends Result { 14 | 15 | /** 16 | * body 17 | */ 18 | @SerializedName("body") 19 | private String body; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/RefundParams.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class RefundParams { 14 | 15 | /** 16 | * 必选 是 17 | * 类型 string 18 | * 说明 订单号 19 | */ 20 | @SerializedName("order_id") 21 | private String orderId; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/RefundResult.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | 9 | @EqualsAndHashCode(callSuper = true) 10 | @Data 11 | @ToString(callSuper = true) 12 | @NoArgsConstructor 13 | public class RefundResult extends Result { 14 | 15 | /** 16 | * code 17 | */ 18 | @SerializedName("code") 19 | private int code; 20 | 21 | /** 22 | * info 23 | */ 24 | @SerializedName("info") 25 | private String info; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/Result.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public abstract class Result { 11 | 12 | /** 13 | * error 14 | */ 15 | private String error; 16 | 17 | public boolean isSuccess(){ 18 | return this.error == null || "".equals(error); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/SearchOrderParams.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class SearchOrderParams { 14 | 15 | /** 16 | * 必选 是 17 | * 类型 string 18 | * 说明 订单号(也支持微信/支付宝流水号) 19 | */ 20 | @SerializedName("out_trade_no") 21 | private String outTradeNo; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/SearchOrderResult.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | 9 | @EqualsAndHashCode(callSuper = true) 10 | @Data 11 | @ToString(callSuper = true) 12 | @NoArgsConstructor 13 | public class SearchOrderResult extends Result { 14 | 15 | 16 | /** 17 | * order_id 18 | */ 19 | @SerializedName("order_id") 20 | private String orderId; 21 | 22 | /** 23 | * charge_id 24 | */ 25 | @SerializedName("charge_id") 26 | private String chargeId; 27 | 28 | /** 29 | * description 30 | */ 31 | @SerializedName("description") 32 | private String description; 33 | 34 | /** 35 | * share_id 36 | */ 37 | @SerializedName("share_id") 38 | private String shareId; 39 | 40 | /** 41 | * share_state 42 | */ 43 | @SerializedName("share_state") 44 | private String shareState; 45 | 46 | /** 47 | * amount 48 | */ 49 | @SerializedName("amount") 50 | private String amount; 51 | 52 | /** 53 | * state 54 | */ 55 | @SerializedName("state") 56 | private String state; 57 | 58 | /** 59 | * create_time 60 | */ 61 | @SerializedName("create_time") 62 | private String createTime; 63 | 64 | /** 65 | * payway 66 | */ 67 | @SerializedName("payway") 68 | private int payway; 69 | 70 | /** 71 | * refund_state 72 | */ 73 | @SerializedName("refund_state") 74 | private String refundState; 75 | 76 | /** 77 | * refund_amount 78 | */ 79 | @SerializedName("refund_amount") 80 | private String refundAmount; 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/WxH5Params.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class WxH5Params { 14 | 15 | /** 16 | * 必选 是 17 | * 类型 string 18 | * 说明 固定为 h5 19 | */ 20 | @SerializedName("channel") 21 | private String channel; 22 | 23 | /** 24 | * 必选 是 25 | * 类型 string 26 | * 说明 支付描述,一般为商品名称 27 | */ 28 | @SerializedName("description") 29 | private String description; 30 | 31 | /** 32 | * 必选 否 33 | * 类型 string 34 | * 说明 订单号,如不填,面包多将随机生成订单号 35 | */ 36 | @SerializedName("out_trade_no") 37 | private String outTradeNo; 38 | 39 | /** 40 | * 必选 是 41 | * 类型 number 42 | * 说明 金额,单位为分 43 | */ 44 | @SerializedName("amount_total") 45 | private int amountTotal; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/WxH5Result.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | 9 | @EqualsAndHashCode(callSuper = true) 10 | @Data 11 | @ToString(callSuper = true) 12 | @NoArgsConstructor 13 | public class WxH5Result extends Result { 14 | 15 | /** 16 | * h5_url 17 | */ 18 | @SerializedName("h5_url") 19 | private String h5Url; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/WxJsApiParams.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class WxJsApiParams { 14 | 15 | /** 16 | * 必选 是 17 | * 类型 string 18 | * 说明 用户的openid,参见获取openid 19 | */ 20 | @SerializedName("openid") 21 | private String openid; 22 | 23 | /** 24 | * 必选 是 25 | * 类型 string 26 | * 说明 支付描述,一般为商品名称 27 | */ 28 | @SerializedName("description") 29 | private String description; 30 | 31 | /** 32 | * 必选 是 33 | * 类型 number 34 | * 说明 金额,单位为分 35 | */ 36 | @SerializedName("amount_total") 37 | private int amountTotal; 38 | 39 | /** 40 | * 必选 否 41 | * 类型 string 42 | * 说明 订单号,如不填,面包多将随机生成订单号 43 | */ 44 | @SerializedName("out_trade_no") 45 | private String outTradeNo; 46 | 47 | /** 48 | * 必选 是 49 | * 类型 string 50 | * 说明 支付后跳转地址 51 | */ 52 | @SerializedName("callback_url") 53 | private String callbackUrl; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/model/WxJsApiResult.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.model; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.NoArgsConstructor; 7 | import lombok.ToString; 8 | 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | @EqualsAndHashCode(callSuper = true) 13 | @Data 14 | @ToString(callSuper = true) 15 | @NoArgsConstructor 16 | public class WxJsApiResult extends Result { 17 | 18 | /** 19 | * appId 20 | */ 21 | @SerializedName("appId") 22 | private String appId; 23 | 24 | /** 25 | * timeStamp 26 | */ 27 | @SerializedName("timeStamp") 28 | private String timeStamp; 29 | 30 | /** 31 | * nonceStr 32 | */ 33 | @SerializedName("nonceStr") 34 | private String nonceStr; 35 | 36 | /** 37 | * package 38 | */ 39 | @SerializedName("package") 40 | private String packageName; 41 | 42 | /** 43 | * signType 44 | */ 45 | @SerializedName("signType") 46 | private String signType; 47 | 48 | /** 49 | * paySign 50 | */ 51 | @SerializedName("paySign") 52 | private String paySign; 53 | 54 | public Map getPayParams() { 55 | HashMap map = new HashMap<>(); 56 | map.put("appId", this.appId); 57 | map.put("timeStamp", this.timeStamp); 58 | map.put("nonceStr", this.nonceStr); 59 | map.put("package", this.packageName); 60 | map.put("signType", this.signType); 61 | map.put("paySign", this.paySign); 62 | return map; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/notice/Notice.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.notice; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * Webhook 通知 10 | */ 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class Notice { 16 | 17 | /** 18 | * type 19 | */ 20 | private NoticeType type; 21 | 22 | /** 23 | * data 24 | */ 25 | private NoticeData data; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/notice/NoticeData.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.notice; 2 | 3 | public interface NoticeData { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/notice/NoticeDataChargeSucceeded.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.notice; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | public class NoticeDataChargeSucceeded implements NoticeData { 10 | 11 | /** 12 | * description 13 | * 类型 string 14 | * 说明 商品描述 15 | */ 16 | @SerializedName("description") 17 | private String description; 18 | 19 | /** 20 | * out_trade_no 21 | * 类型 string 22 | * 说明 订单号 23 | */ 24 | @SerializedName("out_trade_no") 25 | private String outTradeNo; 26 | 27 | /** 28 | * amount 29 | * 类型 int 30 | * 说明 金额,单位为分 31 | */ 32 | @SerializedName("amount") 33 | private int amount; 34 | 35 | /** 36 | * openid 37 | * 类型 string 38 | * 说明 支付者 openid (仅微信支付) 39 | */ 40 | @SerializedName("openid") 41 | private String openid; 42 | 43 | /** 44 | * charge_id 45 | * 类型 string 46 | * 说明 支付渠道流水号 47 | */ 48 | @SerializedName("charge_id") 49 | private String chargeId; 50 | 51 | /** 52 | * payway 53 | * 类型 int 54 | * 说明 支付渠道,微信支付为 1 ,支付宝支付为 2 55 | */ 56 | @SerializedName("payway") 57 | private int payway; 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/notice/NoticeDataComplaint.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.notice; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | public class NoticeDataComplaint implements NoticeData { 12 | 13 | /** 14 | * out_trade_no 15 | * 类型 string 16 | * 说明 订单号 17 | */ 18 | @SerializedName("out_trade_no") 19 | private String outTradeNo; 20 | 21 | /** 22 | * complaint_detail 23 | * 类型 string 24 | * 说明 投诉详情 25 | */ 26 | @SerializedName("complaint_detail") 27 | private String complaintDetail; 28 | 29 | /** 30 | * amount 31 | * 类型 int 32 | * 说明 订单金额,单位为分 33 | */ 34 | @SerializedName("amount") 35 | private int amount; 36 | 37 | /** 38 | * payer_phone 39 | * 类型 string 40 | * 说明 投诉者电话 41 | */ 42 | @SerializedName("payer_phone") 43 | private String payerPhone; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/actar233/mbdpay/notice/NoticeType.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay.notice; 2 | 3 | public enum NoticeType { 4 | charge_succeeded, complaint 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/com/github/actar233/mbdpay/ClientTest.java: -------------------------------------------------------------------------------- 1 | package com.github.actar233.mbdpay; 2 | 3 | import com.github.actar233.mbdpay.exception.MbdPayException; 4 | import com.github.actar233.mbdpay.model.*; 5 | 6 | public class ClientTest { 7 | 8 | public static void main(String[] args) { 9 | MbdPayClient client = new MbdPayClient("", ""); 10 | aliPay(client); 11 | openid(client); 12 | wxH5(client); 13 | wxJsApi(client); 14 | searchOrder(client); 15 | refund(client); 16 | } 17 | 18 | private static void aliPay(MbdPayClient client) { 19 | try { 20 | AliPayResult result = client.aliPay(AliPayParams.builder() 21 | .url("") 22 | .amountTotal(1) 23 | .callbackUrl("") 24 | .description("") 25 | .outTradeNo("<可选:outTradeNo>") 26 | .build()); 27 | if (result.isSuccess()) { 28 | System.out.println("查询成功"); 29 | System.out.println(result); 30 | } else { 31 | System.out.println("查询失败"); 32 | System.out.println(result.getError()); 33 | } 34 | } catch (MbdPayException e) { 35 | System.out.println("请求异常"); 36 | e.printStackTrace(); 37 | } 38 | } 39 | 40 | private static void openid(MbdPayClient client){ 41 | System.out.println(client.openid("https://www.baidu.com")); 42 | } 43 | 44 | private static void wxH5(MbdPayClient client) { 45 | try { 46 | WxH5Result result = client.wxH5(WxH5Params.builder() 47 | .amountTotal(1) 48 | .description("") 49 | .channel("h5") 50 | .outTradeNo("<可选:outTradeNo>") 51 | .build()); 52 | if (result.isSuccess()) { 53 | System.out.println("查询成功"); 54 | System.out.println(result); 55 | } else { 56 | System.out.println("查询失败"); 57 | System.out.println(result.getError()); 58 | } 59 | } catch (MbdPayException e) { 60 | System.out.println("请求异常"); 61 | e.printStackTrace(); 62 | } 63 | } 64 | 65 | private static void wxJsApi(MbdPayClient client) { 66 | try { 67 | WxJsApiResult result = client.wxJsApi(WxJsApiParams.builder() 68 | .openid("") 69 | .amountTotal(1) 70 | .callbackUrl("") 71 | .description("") 72 | .outTradeNo("<可选:outTradeNo>") 73 | .build()); 74 | if (result.isSuccess()) { 75 | System.out.println("查询成功"); 76 | System.out.println(result); 77 | // 获取支付参数 78 | System.out.println(result.getPayParams()); 79 | } else { 80 | System.out.println("查询失败"); 81 | System.out.println(result.getError()); 82 | } 83 | } catch (MbdPayException e) { 84 | System.out.println("请求异常"); 85 | e.printStackTrace(); 86 | } 87 | } 88 | 89 | private static void searchOrder(MbdPayClient client) { 90 | try { 91 | SearchOrderResult result = client.searchOrder(SearchOrderParams.builder() 92 | .outTradeNo("") 93 | .build()); 94 | if (result.isSuccess()) { 95 | System.out.println("查询成功"); 96 | System.out.println(result); 97 | } else { 98 | System.out.println("查询失败"); 99 | System.out.println(result.getError()); 100 | } 101 | } catch (MbdPayException e) { 102 | System.out.println("请求异常"); 103 | e.printStackTrace(); 104 | } 105 | } 106 | 107 | private static void refund(MbdPayClient client) { 108 | try { 109 | RefundResult result = client.refund(RefundParams.builder() 110 | .orderId("") 111 | .build()); 112 | if (result.isSuccess()) { 113 | System.out.println("查询成功"); 114 | System.out.println(result); 115 | } else { 116 | System.out.println("查询失败"); 117 | System.out.println(result.getError()); 118 | } 119 | } catch (MbdPayException e) { 120 | System.out.println("请求异常"); 121 | e.printStackTrace(); 122 | } 123 | } 124 | 125 | } 126 | --------------------------------------------------------------------------------