From dff0bca100df919e9324b80f18f64394fe147985 Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 15 Dec 2020 10:31:51 +0800 Subject: [PATCH 01/15] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/stackoverflow.md | 16 +- .../payment/wechat/enumeration/BankCode.java | 196 +++++++++++++----- .../wechat/enumeration/CouponStatus.java | 10 +- .../wechat/enumeration/StockStatus.java | 14 +- .../wechat/enumeration/TradeState.java | 14 ++ .../payment/wechat/enumeration/TradeType.java | 12 ++ .../wechat/enumeration/WeChatServer.java | 15 ++ .../wechat/enumeration/WechatPayV3Type.java | 77 ++++++- .../payment/wechat/v3/WechatPayScoreApi.java | 20 ++ .../v3/model/combine/CombineAmount.java | 4 + .../payment/wechat/v3/model/payscore/A.java | 31 +++ .../wechat/v3/model/payscore/Location.java | 16 ++ .../v3/model/payscore/PostDiscount.java | 17 ++ .../wechat/v3/model/payscore/PostPayment.java | 20 ++ .../wechat/v3/model/payscore/RiskFund.java | 18 ++ .../wechat/v3/model/payscore/TimeRange.java | 16 ++ 16 files changed, 442 insertions(+), 54 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java diff --git a/docs/stackoverflow.md b/docs/stackoverflow.md index 065c0d4..7baba40 100644 --- a/docs/stackoverflow.md +++ b/docs/stackoverflow.md @@ -7,7 +7,21 @@ - 代金券制券后不能修改,所以一定要注意 - 代金券激活券和制券要有一定的间隔时间,官方说是1分钟 - 发券不需要靠微信服务号,官方的描述是错误的,有一个支持微信登录的appid就行了 -- 不要过分相信微信文档,微信文档不一定是真的,要问就问他们客服 +- 制券 返回`403`,报文`{"code":"REQUEST_BLOCKED","message":"活动未开始或已结束\n"}`检查规则是否符合: + ``` + 1.stock_name:最多可填写9个字 + 2.max_coupons_per_user:单天发放个数上限不能为0 + 3. coupon_amount:10<=coupon_amount<=100000 + 4.available_time_after_receive:可用时间:相对时间,按分钟设置,是否1min<=分钟范围<=1440min + 5.transaction_minimum校验规则: + a、使用门槛-券面额>=0.01(门槛要大于面额) + b、0.1元<=门槛<=100000 + 6.stock_type:目前只支持NORMAL + 7.out_request_no:校验规则:不可以重复 + 8.活动时间不可以大于90天 + ``` + +!> 不要过分相信微信文档,微信文档不一定是真的,要问就问他们客服 ## 支付宝 diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/BankCode.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/BankCode.java index 3ba272e..c25d544 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/BankCode.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/BankCode.java @@ -2,7 +2,7 @@ package cn.felord.payment.wechat.enumeration; /** - * The enum Bank code. + * 银行代码. * * @author felord.cn * @since 1.0.0.RELEASE @@ -10,188 +10,280 @@ package cn.felord.payment.wechat.enumeration; public enum BankCode { /** * 工商银行 + * + * @since 1.0.0.RELEASE */ - BK_1002("1002","工商银行"), + BK_1002("1002", "工商银行"), /** * 农业银行 + * + * @since 1.0.0.RELEASE */ - BK_1005("1005","农业银行"), + BK_1005("1005", "农业银行"), /** * 建设银行 + * + * @since 1.0.0.RELEASE */ - BK_1003("1003","建设银行"), + BK_1003("1003", "建设银行"), /** * 中国银行 + * + * @since 1.0.0.RELEASE */ - BK_1026("1026","中国银行"), + BK_1026("1026", "中国银行"), /** * 交通银行 + * + * @since 1.0.0.RELEASE */ - BK_1020("1020","交通银行"), + BK_1020("1020", "交通银行"), /** * 招商银行 + * + * @since 1.0.0.RELEASE */ - BK_1001("1001","招商银行"), + BK_1001("1001", "招商银行"), /** * 邮储银行 + * + * @since 1.0.0.RELEASE */ - BK_1066("1066","邮储银行"), + BK_1066("1066", "邮储银行"), /** * 民生银行 + * + * @since 1.0.0.RELEASE */ - BK_1006("1006","民生银行"), + BK_1006("1006", "民生银行"), /** * 平安银行 + * + * @since 1.0.0.RELEASE */ - BK_1010("1010","平安银行"), + BK_1010("1010", "平安银行"), /** * 中信银行 + * + * @since 1.0.0.RELEASE */ - BK_1021("1021","中信银行"), + BK_1021("1021", "中信银行"), /** * 浦发银行 + * + * @since 1.0.0.RELEASE */ - BK_1004("1004","浦发银行"), + BK_1004("1004", "浦发银行"), /** * 兴业银行 + * + * @since 1.0.0.RELEASE */ - BK_1009("1009","兴业银行"), + BK_1009("1009", "兴业银行"), /** * 光大银行 + * + * @since 1.0.0.RELEASE */ - BK_1022("1022","光大银行"), + BK_1022("1022", "光大银行"), /** * 广发银行 + * + * @since 1.0.0.RELEASE */ - BK_1027("1027","广发银行"), + BK_1027("1027", "广发银行"), /** * 华夏银行 + * + * @since 1.0.0.RELEASE */ - BK_1025("1025","华夏银行"), + BK_1025("1025", "华夏银行"), /** * 宁波银行 + * + * @since 1.0.0.RELEASE */ - BK_1056("1056","宁波银行"), + BK_1056("1056", "宁波银行"), /** * 北京银行 + * + * @since 1.0.0.RELEASE */ - BK_4836("4836","北京银行"), + BK_4836("4836", "北京银行"), /** * 上海银行 + * + * @since 1.0.0.RELEASE */ - BK_1024("1024","上海银行"), + BK_1024("1024", "上海银行"), /** * 南京银行 + * + * @since 1.0.0.RELEASE */ - BK_1054("1054","南京银行"), + BK_1054("1054", "南京银行"), /** * 长子县融汇村镇银行 + * + * @since 1.0.0.RELEASE */ - BK_4755("4755","长子县融汇村镇银行"), + BK_4755("4755", "长子县融汇村镇银行"), /** * 长沙银行 + * + * @since 1.0.0.RELEASE */ - BK_4216("4216","长沙银行"), + BK_4216("4216", "长沙银行"), /** * 浙江泰隆商业银行 + * + * @since 1.0.0.RELEASE */ - BK_4051("4051","浙江泰隆商业银行"), + BK_4051("4051", "浙江泰隆商业银行"), /** * 中原银行 + * + * @since 1.0.0.RELEASE */ - BK_4753("4753","中原银行"), + BK_4753("4753", "中原银行"), /** * 企业银行(中国) + * + * @since 1.0.0.RELEASE */ - BK_4761("4761","企业银行(中国)"), + BK_4761("4761", "企业银行(中国)"), /** * 顺德农商银行 + * + * @since 1.0.0.RELEASE */ - BK_4036("4036","顺德农商银行"), + BK_4036("4036", "顺德农商银行"), /** * 衡水银行 + * + * @since 1.0.0.RELEASE */ - BK_4752("4752","衡水银行"), + BK_4752("4752", "衡水银行"), /** * 长治银行 + * + * @since 1.0.0.RELEASE */ - BK_4756("4756","长治银行"), + BK_4756("4756", "长治银行"), /** * 大同银行 + * + * @since 1.0.0.RELEASE */ - BK_4767("4767","大同银行"), + BK_4767("4767", "大同银行"), /** * 河南省农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4115("4115","河南省农村信用社"), + BK_4115("4115", "河南省农村信用社"), /** * 宁夏黄河农村商业银行 + * + * @since 1.0.0.RELEASE */ - BK_4150("4150","宁夏黄河农村商业银行"), + BK_4150("4150", "宁夏黄河农村商业银行"), /** * 山西省农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4156("4156","山西省农村信用社"), + BK_4156("4156", "山西省农村信用社"), /** * 安徽省农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4166("4166","安徽省农村信用社"), + BK_4166("4166", "安徽省农村信用社"), /** * 甘肃省农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4157("4157","甘肃省农村信用社"), + BK_4157("4157", "甘肃省农村信用社"), /** * 天津农村商业银行 + * + * @since 1.0.0.RELEASE */ - BK_4153("4153","天津农村商业银行"), + BK_4153("4153", "天津农村商业银行"), /** * 广西壮族自治区农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4113("4113","广西壮族自治区农村信用社"), + BK_4113("4113", "广西壮族自治区农村信用社"), /** * 陕西省农村信用社 + * + * @since 1.0.0.RELEASE */ - BK_4108("4108","陕西省农村信用社"), + BK_4108("4108", "陕西省农村信用社"), /** * 深圳农村商业银行 + * + * @since 1.0.0.RELEASE */ - BK_4076("4076","深圳农村商业银行"), + BK_4076("4076", "深圳农村商业银行"), /** * 宁波鄞州农村商业银行 + * + * @since 1.0.0.RELEASE */ - BK_4052("4052","宁波鄞州农村商业银行"), + BK_4052("4052", "宁波鄞州农村商业银行"), /** * 浙江省农村信用社联合社 + * + * @since 1.0.0.RELEASE */ - BK_4764("4764","浙江省农村信用社联合社"), + BK_4764("4764", "浙江省农村信用社联合社"), /** * 江苏省农村信用社联合社 + * + * @since 1.0.0.RELEASE */ - BK_4217("4217","江苏省农村信用社联合社"), + BK_4217("4217", "江苏省农村信用社联合社"), /** * 江苏紫金农村商业银行股份有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4072("4072","江苏紫金农村商业银行"), + BK_4072("4072", "江苏紫金农村商业银行"), /** * 北京中关村银行股份有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4769("4769","北京中关村银行"), + BK_4769("4769", "北京中关村银行"), /** * 星展银行(中国)有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4778("4778","星展银行(中国)"), + BK_4778("4778", "星展银行(中国)"), /** * 枣庄银行股份有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4766("4766","枣庄银行"), + BK_4766("4766", "枣庄银行"), /** * 海口联合农村商业银行股份有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4758("4758","海口联合农村商业银行"), + BK_4758("4758", "海口联合农村商业银行"), /** * 南洋商业银行(中国)有限公司 + * + * @since 1.0.0.RELEASE */ - BK_4763("4763","南洋商业银行(中国)"); + BK_4763("4763", "南洋商业银行(中国)"); private final String code; @@ -202,10 +294,20 @@ public enum BankCode { this.bankName = bankName; } + /** + * Code string. + * + * @return the string + */ public String code() { return this.code; } + /** + * Bank name string. + * + * @return the string + */ public String bankName() { return this.bankName; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponStatus.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponStatus.java index 8d5128f..64fa511 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponStatus.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/CouponStatus.java @@ -1,22 +1,28 @@ package cn.felord.payment.wechat.enumeration; /** - * The enum Coupon status. + * 代金券状态. * * @author felord.cn * @since 1.0.0.RELEASE */ -public enum CouponStatus { +public enum CouponStatus { /** * 可用. + * + * @since 1.0.0.RELEASE */ SENDED, /** * 已实扣. + * + * @since 1.0.0.RELEASE */ USED, /** * 已过期. + * + * @since 1.0.0.RELEASE */ EXPIRED } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockStatus.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockStatus.java index dd0b84b..a923b5f 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockStatus.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/StockStatus.java @@ -1,7 +1,7 @@ package cn.felord.payment.wechat.enumeration; /** - * The enum Stock status. + * 代金券批次状态. * * @author felord.cn * @since 1.0.0.RELEASE @@ -9,22 +9,32 @@ package cn.felord.payment.wechat.enumeration; public enum StockStatus { /** * Unactivated stock status. + * + * @since 1.0.0.RELEASE */ UNACTIVATED("unactivated", "未激活"), /** * Audit stock status. + * + * @since 1.0.0.RELEASE */ AUDIT("audit", "审核中"), /** * Running stock status. + * + * @since 1.0.0.RELEASE */ RUNNING("running", "运行中"), /** * Stoped stock status. + * + * @since 1.0.0.RELEASE */ STOPED("stoped", "已停止"), /** * Paused stock status. + * + * @since 1.0.0.RELEASE */ PAUSED("paused", "暂停发放"); @@ -40,6 +50,7 @@ public enum StockStatus { * Value string. * * @return the string + * @since 1.0.0.RELEASE */ public String value() { return this.value; @@ -49,6 +60,7 @@ public enum StockStatus { * Description string. * * @return the string + * @since 1.0.0.RELEASE */ public String description() { return this.description; diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeState.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeState.java index b711489..16413e9 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeState.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeState.java @@ -9,30 +9,44 @@ package cn.felord.payment.wechat.enumeration; public enum TradeState { /** * 支付成功 + * + * @since 1.0.0.RELEASE */ SUCCESS, /** * 转入退款 + * + * @since 1.0.0.RELEASE */ REFUND, /** * 未支付 + * + * @since 1.0.0.RELEASE */ NOTPAY, /** * 已关闭 + * + * @since 1.0.0.RELEASE */ CLOSED, /** * 已撤销(付款码支付) + * + * @since 1.0.0.RELEASE */ REVOKED, /** * 用户支付中(付款码支付) + * + * @since 1.0.0.RELEASE */ USERPAYING, /** * 支付失败(其他原因,如银行返回失败) + * + * @since 1.0.0.RELEASE */ PAYERROR, } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeType.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeType.java index 5d5de55..b9ce607 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeType.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/TradeType.java @@ -9,26 +9,38 @@ package cn.felord.payment.wechat.enumeration; public enum TradeType { /** * 公众号支付 + * + * @since 1.0.0.RELEASE */ JSAPI, /** * 扫码支付 + * + * @since 1.0.0.RELEASE */ NATIVE, /** * APP支付 + * + * @since 1.0.0.RELEASE */ APP, /** * 付款码支付 + * + * @since 1.0.0.RELEASE */ MICROPAY, /** * H5支付 + * + * @since 1.0.0.RELEASE */ MWEB, /** * 刷脸支付 + * + * @since 1.0.0.RELEASE */ FACEPAY, } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WeChatServer.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WeChatServer.java index 86b720c..9e5fd84 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WeChatServer.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WeChatServer.java @@ -10,32 +10,46 @@ package cn.felord.payment.wechat.enumeration; public enum WeChatServer { /** * 中国 + * + * @since 1.0.0.RELEASE */ CHINA("https://api.mch.weixin.qq.com"), /** * 中国国内(备用域名) + * + * @since 1.0.0.RELEASE */ CHINA2("https://api2.mch.weixin.qq.com"), /** * 香港 + * + * @since 1.0.0.RELEASE */ HK("https://apihk.mch.weixin.qq.com"), /** * 美国 + * + * @since 1.0.0.RELEASE */ US("https://apius.mch.weixin.qq.com"), /** * 获取公钥 + * + * @since 1.0.0.RELEASE */ FRAUD("https://fraud.mch.weixin.qq.com"), /** * 活动 + * + * @since 1.0.0.RELEASE */ ACTION("https://action.weixin.qq.com"); /** * 域名 + * + * @since 1.0.0.RELEASE */ private final String domain; @@ -47,6 +61,7 @@ public enum WeChatServer { * Gets type. * * @return the type + * @since 1.0.0.RELEASE */ public String domain() { return domain; diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index 0bc9b0c..a68ae7d 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -3,148 +3,215 @@ package cn.felord.payment.wechat.enumeration; import org.springframework.http.HttpMethod; /** - * The Wechat Pay V3 type. + * 微信支付类型. * * @author felord.cn + * @see cn.felord.payment.wechat.v3.WechatPayClient * @since 1.0.0.RELEASE */ public enum WechatPayV3Type { /** * 获取证书. + * + * @since 1.0.0.RELEASE */ CERT(HttpMethod.GET, "%s/v3/certificates"), /** * 文件下载 + * + * @since 1.0.0.RELEASE */ FILE_DOWNLOAD(HttpMethod.GET, "%s/v3/billdownload/file"), /** * 微信公众号支付或者小程序支付. + * + * @since 1.0.0.RELEASE */ JSAPI(HttpMethod.POST, "%s/v3/pay/transactions/jsapi"), /** * 微信扫码支付. + * + * @since 1.0.0.RELEASE */ NATIVE(HttpMethod.POST, "%s/v3/pay/transactions/native"), /** * 微信APP支付. + * + * @since 1.0.0.RELEASE */ APP(HttpMethod.POST, "%s/v3/pay/transactions/app"), /** * H5支付. + * + * @since 1.0.0.RELEASE */ MWEB(HttpMethod.POST, "%s/v3/pay/transactions/h5"), /** * 关闭订单. + * + * @since 1.0.0.RELEASE */ CLOSE(HttpMethod.POST, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}/close"), /** * 微信支付订单号查询. + * + * @since 1.0.0.RELEASE */ TRANSACTION_TRANSACTION_ID(HttpMethod.GET, "%s/v3/pay/transactions/id/{transaction_id}"), /** * 商户订单号查询. + * + * @since 1.0.0.RELEASE */ TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}"), - /** * 合单下单-APP支付API. + * + * @since 1.0.0.RELEASE */ COMBINE_APP(HttpMethod.POST, "%s/v3/combine-transactions/app"), /** * 合单下单-微信公众号支付或者小程序支付. + * + * @since 1.0.0.RELEASE */ COMBINE_JSAPI(HttpMethod.POST, "%s/v3/pay/combine-transactions/jsapi"), /** * 合单下单-H5支付API. + * + * @since 1.0.0.RELEASE */ COMBINE_MWEB(HttpMethod.POST, "%s/v3/pay/combine-transactions/h5"), /** * 合单下单-Native支付API. + * + * @since 1.0.0.RELEASE */ COMBINE_NATIVE(HttpMethod.POST, "%s/v3/pay/combine-transactions/native"), /** * 合单查询订单API. + * + * @since 1.0.0.RELEASE */ COMBINE_TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}"), /** * 合单关闭订单API. + * + * @since 1.0.0.RELEASE */ COMBINE_CLOSE(HttpMethod.POST, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close"), - + /** + * 查询用户授权状态API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET,"%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"), /** * 创建代金券批次API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_COUPON_STOCKS(HttpMethod.POST, "%s/v3/marketing/favor/coupon-stocks"), /** * 激活代金券批次API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_START(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/start"), /** * 暂停代金券批次API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_PAUSE(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/pause"), /** * 发放代金券API、根据商户号查用户的券. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_USERS_COUPONS(HttpMethod.POST, "%s/v3/marketing/favor/users/{openid}/coupons"), /** * 重启代金券API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_RESTART(HttpMethod.POST, "%s/v3/marketing/favor/stocks/{stock_id}/restart"), /** * 条件查询批次列表API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS(HttpMethod.GET, "%s/v3/marketing/favor/stocks"), /** * 查询批次详情API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_DETAIL(HttpMethod.GET, "%s/v3/marketing/favor/stocks/{stock_id}"), /** * 查询代金券详情API + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_USERS_COUPONS_DETAIL(HttpMethod.GET, "%s/v3/marketing/favor/users/{openid}/coupons/{coupon_id}"), /** * 查询代金券可用商户API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_MERCHANTS(HttpMethod.GET, "%s/v3/marketing/favor/stocks/{stock_id}/merchants"), /** * 查询代金券可用单品API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_ITEMS(HttpMethod.GET, "%s/v3/marketing/favor/stocks/{stock_id}/items"), /** * 下载批次核销明细API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_USE_FLOW(HttpMethod.GET, "%s/v3/marketing/favor/stocks/{stock_id}/use-flow"), /** * 下载批次退款明细API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_STOCKS_REFUND_FLOW(HttpMethod.GET, "%s/v3/marketing/favor/stocks/{stock_id}/refund-flow"), /** * 营销图片上传API. + * + * @since 1.0.0.RELEASE */ MARKETING_IMAGE_UPLOAD(HttpMethod.POST, "%s/v3/marketing/favor/media/image-upload"), /** * 设置核销回调通知API. + * + * @since 1.0.0.RELEASE */ MARKETING_FAVOR_CALLBACKS(HttpMethod.POST, "%s/v3/marketing/favor/callbacks"); /** * The Pattern. + * + * @since 1.0.0.RELEASE */ private final String pattern; /** * The Method. + * + * @since 1.0.0.RELEASE */ private final HttpMethod method; @@ -153,6 +220,7 @@ public enum WechatPayV3Type { * * @param method the method * @param pattern the pattern + * @since 1.0.0.RELEASE */ WechatPayV3Type(HttpMethod method, String pattern) { this.method = method; @@ -163,6 +231,7 @@ public enum WechatPayV3Type { * Method string. * * @return the string + * @since 1.0.0.RELEASE */ public HttpMethod method() { return this.method; @@ -172,6 +241,7 @@ public enum WechatPayV3Type { * Pattern string. * * @return the string + * @since 1.0.0.RELEASE */ public String pattern() { return this.pattern; @@ -183,6 +253,7 @@ public enum WechatPayV3Type { * * @param weChatServer the we chat server * @return the string + * @since 1.0.0.RELEASE */ public String uri(WeChatServer weChatServer) { return String.format(this.pattern, weChatServer.domain()); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java new file mode 100644 index 0000000..b4b80d9 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -0,0 +1,20 @@ +package cn.felord.payment.wechat.v3; + +/** + * 微信支付分API. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +public class WechatPayScoreApi extends AbstractApi{ + /** + * Instantiates a new Abstract api. + * + * @param wechatPayClient the wechat pay client + * @param tenantId the tenant id + */ + public WechatPayScoreApi(WechatPayClient wechatPayClient, String tenantId) { + super(wechatPayClient, tenantId); + } + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java index ab9e9fe..f020422 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/combine/CombineAmount.java @@ -14,12 +14,16 @@ import lombok.Data; public class CombineAmount { /** * 符合ISO 4217标准的三位字母代码,必填,人民币:CNY 。 + * + * @since 1.0.0.RELEASE */ private String currency = "CNY"; /** * 子单金额,单位为分,必填 *

* 境外场景下,标价金额要超过商户结算币种的最小单位金额,例如结算币种为美元,则标价金额必须大于1美分 + * + * @since 1.0.0.RELEASE */ private Long totalAmount; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java new file mode 100644 index 0000000..43a2e79 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java @@ -0,0 +1,31 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +import java.util.List; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class A { + + private String appid; + private String attach; + private Location location; + private Boolean needUserConfirm; + private String notifyUrl; + private String openid; + private String outOrderNo; + private List postDiscounts; + private List postPayments; + private RiskFund riskFund; + private String serviceId; + private String serviceIntroduction; + private TimeRange timeRange; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java new file mode 100644 index 0000000..35031f2 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java @@ -0,0 +1,16 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class Location { + private String endLocation; + private String startLocation; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java new file mode 100644 index 0000000..bf42ded --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java @@ -0,0 +1,17 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PostDiscount { + + private String description; + private String name; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java new file mode 100644 index 0000000..5ba3f47 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java @@ -0,0 +1,20 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PostPayment { + + private Long amount; + private Long count; + private String description; + private String name; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java new file mode 100644 index 0000000..6317590 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java @@ -0,0 +1,18 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class RiskFund { + + private Long amount; + private String description; + private String name; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java new file mode 100644 index 0000000..e0947d2 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java @@ -0,0 +1,16 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 微信支付回调请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class TimeRange { + private String endTime; + private String startTime; +} From a71de66dad8d2e72af8faf114ce4421ffbeb445c Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 15 Dec 2020 16:28:00 +0800 Subject: [PATCH 02/15] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=8E=88=E6=9D=83=20=E5=88=9B=E5=BB=BA=E3=80=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E3=80=81=E5=8F=96=E6=B6=88=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=88=86=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/stackoverflow.md | 10 ++ .../wechat/enumeration/WechatPayV3Type.java | 22 ++- .../payment/wechat/v3/WechatApiProvider.java | 17 ++ .../wechat/v3/WechatMarketingFavorApi.java | 10 +- .../payment/wechat/v3/WechatPayScoreApi.java | 148 +++++++++++++++++- .../payment/wechat/v3/model/payscore/A.java | 31 ---- .../payscore/CancelServiceOrderParams.java | 29 ++++ .../wechat/v3/model/payscore/Location.java | 22 ++- .../v3/model/payscore/PostDiscount.java | 23 ++- .../wechat/v3/model/payscore/PostPayment.java | 32 +++- .../payscore/QueryServiceOrderParams.java | 25 +++ .../wechat/v3/model/payscore/RiskFund.java | 47 +++++- .../wechat/v3/model/payscore/TimeRange.java | 40 ++++- .../payscore/UserPayScoreOrderParams.java | 85 ++++++++++ .../payscore/UserServiceStateParams.java | 24 +++ 15 files changed, 515 insertions(+), 50 deletions(-) delete mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CancelServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceStateParams.java diff --git a/docs/stackoverflow.md b/docs/stackoverflow.md index 7baba40..aa73e1d 100644 --- a/docs/stackoverflow.md +++ b/docs/stackoverflow.md @@ -4,7 +4,9 @@ - [Java中的微信支付(2):API V3 微信平台证书的获取与刷新](https://mp.weixin.qq.com/s/O_YcnIRcl2MltElBupm3Hg) - [Java中的微信支付(3):API V3对微信服务器响应进行签名验证](https://mp.weixin.qq.com/s/cb2eTTRjHifNYUGpQETMCQ) ### 微信支付V3中的坑 +#### 代金券 - 代金券制券后不能修改,所以一定要注意 +- 已激活的代金券批次被停用后不影响该批次已发放代金券的核销 - 代金券激活券和制券要有一定的间隔时间,官方说是1分钟 - 发券不需要靠微信服务号,官方的描述是错误的,有一个支持微信登录的appid就行了 - 制券 返回`403`,报文`{"code":"REQUEST_BLOCKED","message":"活动未开始或已结束\n"}`检查规则是否符合: @@ -20,6 +22,14 @@ 7.out_request_no:校验规则:不可以重复 8.活动时间不可以大于90天 ``` +#### 微信支付分 +- 微信支付分`service_id`相关 +``` + 1. 在微信支付分功能申请成功后,联系运营那边配置 service_id。 + 2. service_id 是微信支付商户属性 + 3. 一个 service_id 可以对应多个 mchid + 4. 更多的就要联系微信支付BD了 +``` !> 不要过分相信微信文档,微信文档不一定是真的,要问就问他们客服 diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index a68ae7d..6131821 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -114,7 +114,27 @@ public enum WechatPayV3Type { * * @since 1.0.2.RELEASE */ - PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET,"%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"), + PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET, "%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"), + /** + * 创建支付分订单API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_CREATE_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder"), + /** + * 查询支付分订单API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_QUERY_USER_SERVICE_ORDER(HttpMethod.GET, "%s/v3/payscore/serviceorder"), + /** + * 取消支付分订单API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_CANCEL_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/cancel"), + + /** * 创建代金券批次API. * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java index 0a313c1..4b6c7fc 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatApiProvider.java @@ -26,6 +26,7 @@ public class WechatApiProvider { * * @param tenantId the tenant id * @return the wechat marketing favor api + * @since 1.0.0.RELEASE */ public WechatMarketingFavorApi favorApi(String tenantId) { return new WechatMarketingFavorApi(this.wechatPayClient, tenantId); @@ -36,6 +37,7 @@ public class WechatApiProvider { * * @param tenantId the tenant id * @return the wechat pay api + * @since 1.0.0.RELEASE */ public WechatDirectPayApi directPayApi(String tenantId) { return new WechatDirectPayApi(wechatPayClient, tenantId); @@ -46,16 +48,31 @@ public class WechatApiProvider { * * @param tenantId the tenant id * @return the wechat combine pay api + * @since 1.0.1.RELEASE */ public WechatCombinePayApi combinePayApi(String tenantId) { return new WechatCombinePayApi(wechatPayClient, tenantId); } + /** + * 微信支付分. + * + * @param tenantId the tenant id + * @return the wechat pay score api + * @since 1.0.2.RELEASE + */ + public WechatPayScoreApi payScoreApi(String tenantId) { + return new WechatPayScoreApi(wechatPayClient, tenantId); + } + /** * 回调. * + * 需要处理白名单、幂等性问题。 + * * @param tenantId the tenant id * @return the wechat pay callback + * @since 1.0.0.RELEASE */ public WechatPayCallback callback(String tenantId) { return new WechatPayCallback(wechatPayClient.signatureProvider(), tenantId); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingFavorApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingFavorApi.java index bfa7cbe..292aac2 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingFavorApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatMarketingFavorApi.java @@ -71,12 +71,13 @@ public class WechatMarketingFavorApi extends AbstractApi { * @return the request entity */ private RequestEntity createStocksFunction(WechatPayV3Type type, StocksCreateParams params) { - WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); - String mchId = v3.getMchId(); URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) .build() .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + String mchId = v3.getMchId(); params.setBelongMerchant(mchId); return Post(uri, params); } @@ -220,6 +221,7 @@ public class WechatMarketingFavorApi extends AbstractApi { return wechatResponseEntity; } + /** * Query stocks function request entity. * @@ -374,7 +376,7 @@ public class WechatMarketingFavorApi extends AbstractApi { WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); queryParams.add("stock_creator_mchid", v3.getMchId()); String stockId = params.getStockId(); - URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) + URI uri = UriComponentsBuilder.fromHttpUrl(type.uri(WeChatServer.CHINA)) .queryParams(queryParams) .build() .expand(stockId) @@ -552,7 +554,7 @@ public class WechatMarketingFavorApi extends AbstractApi { Map meta = new LinkedHashMap<>(2); String originalFilename = file.getOriginalFilename(); - String filename = StringUtils.hasText(originalFilename)? originalFilename :file.getName(); + String filename = StringUtils.hasText(originalFilename) ? originalFilename : file.getName(); meta.put("filename", filename); byte[] digest = SHA256.Digest.getInstance("SHA-256").digest(file.getBytes()); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java index b4b80d9..ce3017b 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -1,12 +1,27 @@ package cn.felord.payment.wechat.v3; +import cn.felord.payment.wechat.WechatPayProperties; +import cn.felord.payment.wechat.enumeration.WeChatServer; +import cn.felord.payment.wechat.enumeration.WechatPayV3Type; +import cn.felord.payment.wechat.v3.model.payscore.CancelServiceOrderParams; +import cn.felord.payment.wechat.v3.model.payscore.QueryServiceOrderParams; +import cn.felord.payment.wechat.v3.model.payscore.UserPayScoreOrderParams; +import cn.felord.payment.wechat.v3.model.payscore.UserServiceStateParams; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; + /** * 微信支付分API. * * @author felord.cn * @since 1.0.2.RELEASE */ -public class WechatPayScoreApi extends AbstractApi{ +public class WechatPayScoreApi extends AbstractApi { /** * Instantiates a new Abstract api. * @@ -17,4 +32,135 @@ public class WechatPayScoreApi extends AbstractApi{ super(wechatPayClient, tenantId); } + /** + * 微信支付分-查询用户授权状态API. + *

+ * 免确认订单起始接口,【免确认订单模式】是高级接口权限,参见:业务流程说明 + *

+ * 用户申请使用服务时,商户可通过此接口查询用户是否“已授权”本服务。在“已授权”状态下的服务,用户才可以申请使用。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity userServiceState(UserServiceStateParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_USER_SERVICE_STATE, params) + .function((wechatPayV3Type, userServiceStateParams) -> { + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + + MultiValueMap expandParams = new LinkedMultiValueMap<>(); + expandParams.add("appid", v3.getAppId()); + expandParams.add("service_id", params.getServiceId()); + expandParams.add("openid", params.getOpenId()); + + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(expandParams) + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 创建支付分订单API + *

+ * 用户申请使用服务时,商户可通过此接口申请创建微信支付分订单。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity createServiceOrder(UserPayScoreOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_CREATE_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + + orderParams.setAppid(v3.getAppId()); + orderParams.setNotifyUrl(v3.getDomain().concat(orderParams.getNotifyUrl())); + + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .toUri(); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 查询支付分订单API + *

+ * 用于查询单笔微信支付分订单详细信息。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity queryServiceOrder(QueryServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_QUERY_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + MultiValueMap queryParams = new LinkedMultiValueMap<>(); + + String outOrderNo = orderParams.getOutOrderNo(); + if (StringUtils.hasText(outOrderNo)) { + queryParams.add("out_order_no", outOrderNo); + } + + String queryId = orderParams.getQueryId(); + if (StringUtils.hasText(queryId)) { + queryParams.add("query_id", queryId); + } + queryParams.add("service_id", orderParams.getServiceId()); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + queryParams.add("appid", v3.getAppId()); + + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .queryParams(queryParams) + .build() + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 取消支付分订单API + *

+ * 微信支付分订单创建之后,由于某些原因导致订单不能正常支付时,可使用此接口取消订单。 + *

+ * 订单为以下状态时可以取消订单:CREATED(已创单)、DOING(进行中)(包括商户完结支付分订单后,且支付分订单收款状态为待支付USER_PAYING) + *

+ * 注意: + * • DOING状态包含了订单用户确认、已完结-待支付(USER_PAYING)的状态,因此这种状态下订单也是可以被取消的,请确认当前操作是否正确,防止误操作将完结后需要支付分收款的单据取消。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity cancelServiceOrder(CancelServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_CANCEL_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + orderParams.setOutOrderNo(null); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java deleted file mode 100644 index 43a2e79..0000000 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/A.java +++ /dev/null @@ -1,31 +0,0 @@ - -package cn.felord.payment.wechat.v3.model.payscore; - - -import lombok.Data; - -import java.util.List; - -/** - * 微信支付回调请求参数. - * - * @author felord.cn - * @since 1.0.2.RELEASE - */ -@Data -public class A { - - private String appid; - private String attach; - private Location location; - private Boolean needUserConfirm; - private String notifyUrl; - private String openid; - private String outOrderNo; - private List postDiscounts; - private List postPayments; - private RiskFund riskFund; - private String serviceId; - private String serviceIntroduction; - private TimeRange timeRange; -} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CancelServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CancelServiceOrderParams.java new file mode 100644 index 0000000..a9d2f2c --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CancelServiceOrderParams.java @@ -0,0 +1,29 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 取消支付分订单请求参数 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class CancelServiceOrderParams { + /** + * 商户服务订单号,必填 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + */ + private String serviceId; + /** + * 取消原因,最长50个字符,必填 + */ + private String reason; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java index 35031f2..20263eb 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/Location.java @@ -4,13 +4,31 @@ package cn.felord.payment.wechat.v3.model.payscore; import lombok.Data; /** - * 微信支付回调请求参数. + * 服务位置信息 + *

+ * 如果传入,用户侧则显示此参数。 * * @author felord.cn * @since 1.0.2.RELEASE */ @Data public class Location { - private String endLocation; + + /** + * 服务开始地点,选填。 + *

+ * 开始使用服务的地点,不超过50个字符,超出报错处理。 + * 【建议】 + * 1、用户下单时【未确定】服务结束地点,不填写。 + * 2、服务在同一地点开始和结束,不填写。 + * 3、用户下单时【已确定】服务结束地点,填写。 + */ private String startLocation; + /** + * 预计服务结束地点,有开始地点时为必填。 + * + * 1、结束使用服务的地点,不超过50个字符,超出报错处理 。 + * 2、填写了服务开始地点,才能填写服务结束地点。 + */ + private String endLocation; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java index bf42ded..803deb0 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java @@ -4,7 +4,9 @@ package cn.felord.payment.wechat.v3.model.payscore; import lombok.Data; /** - * 微信支付回调请求参数. + * 后付费商户优惠,选填 + *

+ * 最多包含30条商户优惠。如果传入,用户侧则显示此参数。 * * @author felord.cn * @since 1.0.2.RELEASE @@ -12,6 +14,23 @@ import lombok.Data; @Data public class PostDiscount { - private String description; + /** + * 优惠名称,条件选填 + * + * 优惠名称说明;name和description若填写,则必须同时填写,优惠名称不可重复描述。 + */ private String name; + /** + * 优惠说明,条件选填 + * + * 优惠使用条件说明。{@link PostDiscount#name}若填写,则必须同时填写。 + */ + private String description; + /** + * 优惠数量,选填。 + *

+ * 优惠的数量。 + * 特殊规则:数量限制100,不填时默认1。 + */ + private Long count = 1L; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java index 5ba3f47..51502e0 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java @@ -4,17 +4,39 @@ package cn.felord.payment.wechat.v3.model.payscore; import lombok.Data; /** - * 微信支付回调请求参数. + * 后付费项目,选填 + *

+ * 最多包含100条付费项目。如果传入,用户侧则显示此参数。 * * @author felord.cn * @since 1.0.2.RELEASE */ @Data public class PostPayment { - - private Long amount; - private Long count; - private String description; + /** + * 付费项目名称,选填。 + *

+ * 相同订单号下不能出现相同的付费项目名称,当参数长度超过20个字符时,报错处理。 + */ private String name; + /** + * 金额,条件选填。 + *

+ * 此付费项目总金额,大于等于0,单位为分,等于0时代表不需要扣费,只能为整数,详见支付金额。如果填写了“付费项目名称”,则amount或description必须填写其一,或都填。 + */ + private Long amount; + /** + * 计费说明,条件选填。 + *

+ * 描述计费规则,不超过30个字符,超出报错处理。如果填写了“付费项目名称”,则amount或description必须填写其一,或都填。 + */ + private String description; + /** + * 付费数量,选填。 + *

+ * 付费项目的数量。 + * 特殊规则:数量限制100,不填时默认1。 + */ + private Long count = 1L; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java new file mode 100644 index 0000000..6a16f85 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java @@ -0,0 +1,25 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 查询支付分订单请求参数 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class QueryServiceOrderParams { + /** + * 商户服务订单号,同{@link QueryServiceOrderParams#queryId} 二选一,而且不能同时为{@link null} + */ + private String outOrderNo; + /** + * 回跳查询ID,同{@link QueryServiceOrderParams#outOrderNo} 二选一,而且不能同时为{@link null} + */ + private String queryId; + /** + * 服务ID,必填 + */ + private String serviceId; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java index 6317590..746a624 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java @@ -4,7 +4,7 @@ package cn.felord.payment.wechat.v3.model.payscore; import lombok.Data; /** - * 微信支付回调请求参数. + * 订单风险金信息,必填 * * @author felord.cn * @since 1.0.2.RELEASE @@ -12,7 +12,50 @@ import lombok.Data; @Data public class RiskFund { + /** + * 风险金名称,必填 + */ + private Type name; + /** + * 风险金额,必填 + *

+ * 1、数字,必须>0(单位分)。 + * 2、风险金额≤每个服务ID的风险金额上限。 + * 3、当商户优惠字段为空时,付费项目总金额≤服务ID的风险金额上限 (未填写金额的付费项目,视为该付费项目金额为0)。 + * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 + */ private Long amount; + /** + * 风险说明,选填 + *

+ * 文字,不超过30个字。 + */ private String description; - private String name; + + + /** + * 风险金类型 + */ + enum Type { + /** + * 押金 + */ + DEPOSIT, + /** + * 预付款 + */ + ADVANCE, + /** + * 保证金 + */ + CASH_DEPOSIT, + /** + * 预估订单费用 + *

+ * 【先享模式】(评估不通过不可使用服务) + */ + ESTIMATE_ORDER_COST + } + + } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java index e0947d2..1fcb04e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java @@ -4,13 +4,49 @@ package cn.felord.payment.wechat.v3.model.payscore; import lombok.Data; /** - * 微信支付回调请求参数. + * 服务时间段,必填 * * @author felord.cn * @since 1.0.2.RELEASE */ @Data public class TimeRange { - private String endTime; + /** + * 服务开始时间 + *

+ * 用户端展示用途。 + * 用户下单时确认的服务开始时间(比如用户今天下单,明天开始接受服务,这里指的是明天的服务开始时间)。 + * 支持三种格式:yyyyMMddHHmmss、yyyyMMdd和 OnAccept + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225默认认为时间为2009年12月25日 + * ● 传入OnAccept表示用户确认订单成功时间为【服务开始时间】。 + * 根据传入时间精准度进行校验 + * 1)若传入时间精准到秒,则校验精准到秒:【服务开始时间】>【商户调用创建订单接口时间 + * 2)若传入时间精准到日,则校验精准到日:【服务开始时间】>=【商户调用创建订单接口时间】 + */ private String startTime; + /** + * 服务开始时间备注说明,服务开始时间有填时,可填写服务开始时间备注,不超过20个字符,超出报错处理。 + */ + private String startTimeRemark; + /** + * 用户端展示用途,支持两种格式:yyyyMMddHHmmss和yyyyMMdd + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225默认认为时间为2009年12月25日 + * 根据传入时间精准度进行校验 + * 1、若传入时间精准到秒,则校验精准到秒: + * 1)【预计服务结束时间】>【服务开始时间】 + * 2)【预计服务结束时间】>【商户调用接口时间+1分钟】 + * 2、若传入时间精准到日,则校验精准到日: + * 1)【预计服务结束时间】>=【服务开始时间】 + * 2)【预计服务结束时间】>=【商户调用接口时间】 + * 【建议】 + * 1、用户下单时【未确定】服务结束时间,不填写。 + * 2、用户下单时【已确定】服务结束时间,填写。 + */ + private String endTime; + /** + * 预计服务结束时间备注说明,预计服务结束时间有填时,可填写预计服务结束时间备注,不超过20个字符,超出报错处理。 + */ + private String endTimeRemark; } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java new file mode 100644 index 0000000..dba2540 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java @@ -0,0 +1,85 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +import java.util.List; + +/** + * 创建支付分订单请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class UserPayScoreOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; + /** + * 服务信息,必填 + *

+ * 用于介绍本订单所提供的服务 ,当参数长度超过20个字符时,报错处理。 + */ + private String serviceIntroduction; + /** + * 后付费项目,选填 + */ + private List postPayments; + /** + * 后付费商户优惠,选填 + */ + private List postDiscounts; + /** + * 服务时间段,必填 + */ + private TimeRange timeRange; + /** + * 服务位置,选填 + */ + private Location location; + /** + * 订单风险金,必填 + */ + private RiskFund riskFund; + /** + * 商户数据包,选填 + *

+ * 商户数据包可存放本订单所需信息,需要先urlencode后传入。 当商户数据包总长度超出256字符时,报错处理。 + */ + private String attach; + /** + * 商户回调地址,必填 + */ + private String notifyUrl; + /** + * 微信用户在商户对应appid下的唯一标识,条件选填 + *

+ * 免确认订单:必填 + * 需确认订单:不填 + */ + private String openid; + /** + * 是否需要用户确认,选填 + *

+ * false:免确认订单 + * true:需确认订单 + * 默认值true + */ + private Boolean needUserConfirm = Boolean.TRUE; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceStateParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceStateParams.java new file mode 100644 index 0000000..0592a28 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceStateParams.java @@ -0,0 +1,24 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 查询用户授权状态参数. + *

+ * {@code appid} 从对应租户的配置中自动注入。 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class UserServiceStateParams { + /** + * 微信支付分 服务ID , 需要微信侧运营操作绑定到商户。 + */ + private String serviceId; + /** + * 微信用户在商户对应appid下的唯一标识。 + */ + private String openId; + +} From bbdbe44b0b8fbec9bc778750e2faba55cde880e3 Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 15 Dec 2020 16:31:03 +0800 Subject: [PATCH 03/15] branch version to 1.0.2.RELEASE --- payment-spring-boot-autoconfigure/pom.xml | 4 ++-- payment-spring-boot-starter/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/payment-spring-boot-autoconfigure/pom.xml b/payment-spring-boot-autoconfigure/pom.xml index 452998d..bae82a5 100644 --- a/payment-spring-boot-autoconfigure/pom.xml +++ b/payment-spring-boot-autoconfigure/pom.xml @@ -5,11 +5,11 @@ cn.felord payment-spring-boot - 1.0.1.RELEASE + 1.0.2.RELEASE payment-spring-boot-autoconfigure - 1.0.1.RELEASE + 1.0.2.RELEASE jar 4.0.0 diff --git a/payment-spring-boot-starter/pom.xml b/payment-spring-boot-starter/pom.xml index a05cf14..d738dc4 100644 --- a/payment-spring-boot-starter/pom.xml +++ b/payment-spring-boot-starter/pom.xml @@ -5,11 +5,11 @@ cn.felord payment-spring-boot - 1.0.1.RELEASE + 1.0.2.RELEASE payment-spring-boot-starter - 1.0.1.RELEASE + 1.0.2.RELEASE jar 4.0.0 diff --git a/pom.xml b/pom.xml index 2789c15..2130491 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> cn.felord payment-spring-boot - 1.0.1.RELEASE + 1.0.2.RELEASE pom 4.0.0 From a3b595a8dd0a0c660617433dd9dd82d14cc07118 Mon Sep 17 00:00:00 2001 From: xiafang Date: Tue, 15 Dec 2020 19:20:46 +0800 Subject: [PATCH 04/15] wechat pay score api --- .../wechat/enumeration/WechatPayV3Type.java | 56 ++++++++ .../payment/wechat/v3/SignatureProvider.java | 29 ++-- .../payment/wechat/v3/WechatPayCallback.java | 2 +- .../payment/wechat/v3/WechatPayScoreApi.java | 135 +++++++++++++++++- .../payscore/CompleteServiceOrderParams.java | 94 ++++++++++++ .../payscore/ModifyServiceOrderParams.java | 53 +++++++ .../model/payscore/PayServiceOrderParams.java | 30 ++++ .../v3/model/payscore/PostDiscount.java | 5 + .../wechat/v3/model/payscore/PostPayment.java | 4 +- .../wechat/v3/model/payscore/RiskFund.java | 2 +- .../payscore/SyncServiceOrderParams.java | 64 +++++++++ ...arams.java => UserServiceOrderParams.java} | 2 +- 12 files changed, 447 insertions(+), 29 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java rename payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/{UserPayScoreOrderParams.java => UserServiceOrderParams.java} (98%) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index 6131821..7017f02 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -109,12 +109,44 @@ public enum WechatPayV3Type { */ COMBINE_CLOSE(HttpMethod.POST, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close"), + /** + * 商户预授权API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_PERMISSIONS(HttpMethod.POST, "%s/v3/payscore/permissions"), + /** + * 查询与用户授权记录(授权协议号)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_QUEERY_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.GET, "%s/v3/payscore/permissions/authorization-code/{authorization_code}"), + /** + * 解除用户授权关系(授权协议号)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_TERMINATE_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.POST, "%s/v3/payscore/permissions/authorization-code/{authorization_code}/terminate"), + /** + * 查询与用户授权记录(openid)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_PERMISSIONS_OPENID(HttpMethod.GET, "%s/v3/payscore/permissions/openid/{openid}"), + /** + * 解除用户授权关系(openid)API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_TERMINATE_PERMISSIONS_OPENID(HttpMethod.POST, "%s/v3/payscore/permissions/openid/{openid}/terminate"), /** * 查询用户授权状态API. * * @since 1.0.2.RELEASE */ PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET, "%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"), + + /** * 创建支付分订单API * @@ -133,6 +165,30 @@ public enum WechatPayV3Type { * @since 1.0.2.RELEASE */ PAY_SCORE_CANCEL_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/cancel"), + /** + * 修改订单金额API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_MODIFY_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/modify"), + /** + * 完结支付分订单API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_COMPLETE_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/complete"), + /** + * 商户发起催收扣款API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_PAY_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/pay"), + /** + * 同步服务订单信息API + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_SYNC_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/sync"), /** diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java index a3e9980..b69182e 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/SignatureProvider.java @@ -86,7 +86,7 @@ public class SignatureProvider { /** - * 我方请求时加签,使用API证书. + * 我方请求前用 SHA256withRSA 加签,使用API证书. * * @param tenantId the properties key * @param method the method @@ -95,7 +95,7 @@ public class SignatureProvider { * @return the string */ @SneakyThrows - public String requestSign(String tenantId,String method, String canonicalUrl, String body) { + public String requestSign(String tenantId, String method, String canonicalUrl, String body) { Signature signer = Signature.getInstance("SHA256withRSA"); WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId); signer.initSign(wechatMetaBean.getKeyPair().getPrivate()); @@ -160,7 +160,7 @@ public class SignatureProvider { } // 签名 HttpMethod httpMethod = WechatPayV3Type.CERT.method(); - String authorization = requestSign(tenantId,httpMethod.name(), canonicalUrl, ""); + String authorization = requestSign(tenantId, httpMethod.name(), canonicalUrl, ""); HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); @@ -177,30 +177,27 @@ public class SignatureProvider { ArrayNode certificates = bodyObjectNode.withArray("data"); if (certificates.isArray() && certificates.size() > 0) { CERTIFICATE_MAP.clear(); - final CertificateFactory cf = CertificateFactory.getInstance("X509"); + final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); certificates.forEach(objectNode -> { JsonNode encryptCertificate = objectNode.get("encrypt_certificate"); String associatedData = encryptCertificate.get("associated_data").asText(); String nonce = encryptCertificate.get("nonce").asText(); String ciphertext = encryptCertificate.get("ciphertext").asText(); - String publicKey = decryptResponseBody(tenantId,associatedData, nonce, ciphertext); + String publicKey = decryptResponseBody(tenantId, associatedData, nonce, ciphertext); ByteArrayInputStream inputStream = new ByteArrayInputStream(publicKey.getBytes(StandardCharsets.UTF_8)); - Certificate certificate = null; + try { - certificate = cf.generateCertificate(inputStream); + Certificate certificate = certificateFactory.generateCertificate(inputStream); + String responseSerialNo = objectNode.get("serial_no").asText(); + CERTIFICATE_MAP.put(responseSerialNo, certificate); } catch (CertificateException e) { - e.printStackTrace(); + throw new PayException("An error occurred while generating the wechat v3 certificate, reason : " + e.getMessage()); } - String responseSerialNo = objectNode.get("serial_no").asText(); - CERTIFICATE_MAP.put(responseSerialNo, certificate); }); - } - } - /** * 解密响应体. * @@ -210,7 +207,7 @@ public class SignatureProvider { * @param ciphertext the ciphertext * @return the string */ - public String decryptResponseBody(String tenantId,String associatedData, String nonce, String ciphertext) { + public String decryptResponseBody(String tenantId, String associatedData, String nonce, String ciphertext) { try { Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); String apiV3Key = wechatMetaContainer.getWechatMeta(tenantId).getV3().getAppV3Secret(); @@ -233,7 +230,6 @@ public class SignatureProvider { } } - /** * Wechat meta container. * @@ -249,10 +245,9 @@ public class SignatureProvider { * @param components the components * @return string string */ - private String createSign(String... components) { + private static String createSign(String... components) { return Arrays.stream(components) .collect(Collectors.joining("\n", "", "\n")); } - } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java index f38b7e1..72bc8dc 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java @@ -19,7 +19,7 @@ import java.util.function.Consumer; * 微信支付回调工具. *

* 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。 - * + * TODO 微信支付分有三个回调通知 * @author felord.cn * @since 1.0.0.RELEASE */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java index ce3017b..c541967 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -3,10 +3,7 @@ package cn.felord.payment.wechat.v3; import cn.felord.payment.wechat.WechatPayProperties; import cn.felord.payment.wechat.enumeration.WeChatServer; import cn.felord.payment.wechat.enumeration.WechatPayV3Type; -import cn.felord.payment.wechat.v3.model.payscore.CancelServiceOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.QueryServiceOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.UserPayScoreOrderParams; -import cn.felord.payment.wechat.v3.model.payscore.UserServiceStateParams; +import cn.felord.payment.wechat.v3.model.payscore.*; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -72,7 +69,7 @@ public class WechatPayScoreApi extends AbstractApi { * @param params the params * @return the wechat response entity */ - public WechatResponseEntity createServiceOrder(UserPayScoreOrderParams params) { + public WechatResponseEntity createServiceOrder(UserServiceOrderParams params) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.PAY_SCORE_CREATE_USER_SERVICE_ORDER, params) .function((wechatPayV3Type, orderParams) -> { @@ -147,16 +144,140 @@ public class WechatPayScoreApi extends AbstractApi { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); this.client().withType(WechatPayV3Type.PAY_SCORE_CANCEL_USER_SERVICE_ORDER, params) .function((wechatPayV3Type, orderParams) -> { - URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) .build() .expand(orderParams.getOutOrderNo()) .toUri(); - orderParams.setOutOrderNo(null); WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + /** + * 修改订单金额API + *

+ * 完结订单总金额与实际金额不符时,可通过该接口修改订单金额。 + * 例如:充电宝场景,由于机器计费问题导致商户完结订单时扣除用户99元,用户客诉成功后,商户需要按照实际的消费金额(如10元)扣费,当服务订单支付状态处于“待支付”时,商户可使用此能力修改订单金额。 + *

+ * 注意: + * • 若此笔订单已收款成功,商户直接使用退款能力,将差价退回用户即可。 + *

+ * • 修改次数>=1,第n次修改后金额 <第n-1次修改后金额 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity modifyServiceOrder(ModifyServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_MODIFY_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 完结支付分订单API + *

+ * 前置条件:服务订单状态为“进行中”且订单状态说明需为[USER_CONFIRM:用户确认] + *

+ * 完结微信支付分订单。用户使用服务完成后,商户可通过此接口完结订单。 + *

+ * 特别说明: + * • 完结接口调用成功后,微信支付将自动发起免密代扣。 若扣款失败,微信支付将自动再次发起免密代扣(按照一定频次),直到扣成功为止。 + * + * @param params the params + * @return wechat response entity + */ + public WechatResponseEntity completeServiceOrder(CompleteServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_COMPLETE_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 商户发起催收扣款API + *

+ * 前置条件:服务订单支付状态处于“待支付”状态 + *

+ * 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款。 + *

+ * 注意: + * • 此能力不影响微信支付分代商户向用户发起收款的策略。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity payServiceOrder(PayServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PAY_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 同步服务订单信息API + *

+ * 前提条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”,订单的状态需为[MCH_COMPLETE:商户完结订单] + *

+ * 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity syncServiceOrder(SyncServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_SYNC_USER_SERVICE_ORDER, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOutOrderNo()) + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOutOrderNo(null); return Post(uri, orderParams); }) .consumer(wechatResponseEntity::convert) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java new file mode 100644 index 0000000..93380bd --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/CompleteServiceOrderParams.java @@ -0,0 +1,94 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +import java.util.List; + +/** + * 完结支付分订单请求参数 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class CompleteServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; + /** + * 后付费项目,必填 + */ + private List postPayments; + /** + * 后付费商户优惠,选填 + */ + private List postDiscounts; + /** + * 总金额,单位分,必填 + *

+ * 不能超过完结订单时候的总金额,只能为整数,详见 支付金额。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n) + */ + private Long totalAmount; + /** + * 服务时间段,条件选填 + *

+ * 服务时间范围,创建订单未填写服务结束时间,则完结的时候,服务结束时间必填 + * 如果传入,用户侧则显示此参数。 + */ + private TimeRange timeRange; + /** + * 服务位置,选填 + */ + private CompleteLocation location; + /** + * 微信支付服务分账标记,选填 + *

+ * 完结订单分账接口标记。分账开通流程,详见 分账 + * false:不分账,默认:false + * true:分账。 + */ + private Boolean profitSharing = Boolean.TRUE; + /** + * 订单优惠标记,选填 + *

+ * 代金券或立减金优惠的参数,说明详见代金券或立减金优惠 + */ + private String goods_tag; + + + /** + * 服务位置信息 + *

+ * 如果传入,用户侧则显示此参数。 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ + @Data + public static class CompleteLocation { + + /** + * 预计服务结束地点,条件选填。 + *

+ * 结束使用服务的地点,不超过50个字符,超出报错处理 。 创建订单传入了【服务开始地点】,此项才能填写 + * 【建议】 + * 1、预计结束地点为空时,实际结束地点与开始地点相同,不填写 + * 2、预计结束地点不为空时,实际结束地点与预计结束地点相同,不填写 + */ + private String endLocation; + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java new file mode 100644 index 0000000..f7b3816 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ModifyServiceOrderParams.java @@ -0,0 +1,53 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +import java.util.List; + +/** + * 修改微信支付分订单金额请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class ModifyServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。需要与创建订单时保持一致。 + */ + private String serviceId; + /** + * 后付费项目,必填 + */ + private List postPayments; + /** + * 后付费商户优惠,选填 + */ + private List postDiscounts; + /** + * 总金额,单位分,必填 + * + * 不能超过完结订单时候的总金额,只能为整数,详见 支付金额。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n) + */ + private Long totalAmount; + /** + * 取消原因,最长50个字符,必填 + */ + private String reason; + +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java new file mode 100644 index 0000000..ce472a3 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayServiceOrderParams.java @@ -0,0 +1,30 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 商户发起催收扣款请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PayServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java index 803deb0..7b253b4 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostDiscount.java @@ -26,6 +26,11 @@ public class PostDiscount { * 优惠使用条件说明。{@link PostDiscount#name}若填写,则必须同时填写。 */ private String description; + /** + * 总金额,单位分,必填 + * todo 新增没有此字段,修改必填,感觉不太符合常理 + */ + private Long amount; /** * 优惠数量,选填。 *

diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java index 51502e0..ededb85 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PostPayment.java @@ -14,13 +14,13 @@ import lombok.Data; @Data public class PostPayment { /** - * 付费项目名称,选填。 + * 付费项目名称,选填。 修改订单必填 *

* 相同订单号下不能出现相同的付费项目名称,当参数长度超过20个字符时,报错处理。 */ private String name; /** - * 金额,条件选填。 + * 金额,条件选填。修改订单必填 *

* 此付费项目总金额,大于等于0,单位为分,等于0时代表不需要扣费,只能为整数,详见支付金额。如果填写了“付费项目名称”,则amount或description必须填写其一,或都填。 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java index 746a624..31da2de 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java @@ -22,7 +22,7 @@ public class RiskFund { * 1、数字,必须>0(单位分)。 * 2、风险金额≤每个服务ID的风险金额上限。 * 3、当商户优惠字段为空时,付费项目总金额≤服务ID的风险金额上限 (未填写金额的付费项目,视为该付费项目金额为0)。 - * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 + * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 */ private Long amount; /** diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java new file mode 100644 index 0000000..7764199 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/SyncServiceOrderParams.java @@ -0,0 +1,64 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 同步服务订单信息请求参数. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class SyncServiceOrderParams { + + /** + * 商户服务订单号,必填 + *

+ * 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String outOrderNo; + /** + * 与传入的商户号建立了支付绑定关系的appid,必填 + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。与订单要保持一致。 + */ + private String serviceId; + /** + * 场景类型,必填,场景类型为“Order_Paid”,字符串表示“订单收款成功” 。 + */ + private String type = "Order_Paid"; + + /** + * 内容信息详情,场景类型为Order_Paid时,为必填项。 + */ + private SyncDetail detail; + + + /** + * 内容信息详情 + */ + @Data + public static class SyncDetail{ + /** + * 收款成功时间 + *

+ * 支付成功时间,支持两种格式:yyyyMMddHHmmss和yyyyMMdd + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225默认认为时间为2009年12月25日0点0分0秒。 + * 用户通过其他方式付款成功的实际时间需满足条件:服务开始时间<调用商户完结订单接口的时间<用户通过其他方式付款成功的实际时间≤商户调用支付分订单同步接口的时间。 + * 【服务开始时间】 + * 1、当完结订单有填写【实际服务开始时间】时,【服务开始时间】=完结订单【实际服务开始时间】。 + * 2、当完结订单未填写【实际服务开始时间】时,【服务开始时间】=创建订单【服务开始时间】 + * 场景类型为Order_Paid时,必填。 + * 支持两种格式:yyyyMMddHHmmss和yyyyMMdd + * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + * ● 传入20091225表示时间为2009年12月25日23点59分59秒。 + * 注意:微信支付分会根据此时间更新用户侧的守约记录、负面记录信息;因此请务必如实填写用户实际付款成功时间,以免造成不必要的客诉。 + */ + private String paidTime; + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java similarity index 98% rename from payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java rename to payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java index dba2540..5b5e612 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserPayScoreOrderParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/UserServiceOrderParams.java @@ -13,7 +13,7 @@ import java.util.List; * @since 1.0.2.RELEASE */ @Data -public class UserPayScoreOrderParams { +public class UserServiceOrderParams { /** * 商户服务订单号,必填 From 8742c86024375308032ed057d35e8ea543c2f6c3 Mon Sep 17 00:00:00 2001 From: "felord.cn" Date: Wed, 16 Dec 2020 00:03:36 +0800 Subject: [PATCH 05/15] doc bugfix --- .../payment/wechat/v3/WechatPayScoreApi.java | 2 +- .../payscore/QueryServiceOrderParams.java | 4 +-- .../wechat/v3/model/payscore/RiskFund.java | 4 +-- .../wechat/v3/model/payscore/TimeRange.java | 26 ++++++++++++++----- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java index c541967..6fa50ea 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -168,7 +168,7 @@ public class WechatPayScoreApi extends AbstractApi { * 注意: * • 若此笔订单已收款成功,商户直接使用退款能力,将差价退回用户即可。 *

- * • 修改次数>=1,第n次修改后金额 <第n-1次修改后金额 + * • 修改次数>=1,第n次修改后金额 <第n-1次修改后金额 * * @param params the params * @return the wechat response entity diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java index 6a16f85..326dc7a 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/QueryServiceOrderParams.java @@ -11,11 +11,11 @@ import lombok.Data; @Data public class QueryServiceOrderParams { /** - * 商户服务订单号,同{@link QueryServiceOrderParams#queryId} 二选一,而且不能同时为{@link null} + * 商户服务订单号,同{@link QueryServiceOrderParams#queryId} 二选一,而且不能同时为null */ private String outOrderNo; /** - * 回跳查询ID,同{@link QueryServiceOrderParams#outOrderNo} 二选一,而且不能同时为{@link null} + * 回跳查询ID,同{@link QueryServiceOrderParams#outOrderNo} 二选一,而且不能同时为null */ private String queryId; /** diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java index 31da2de..8ae9654 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/RiskFund.java @@ -19,8 +19,8 @@ public class RiskFund { /** * 风险金额,必填 *

- * 1、数字,必须>0(单位分)。 - * 2、风险金额≤每个服务ID的风险金额上限。 + * 1、数字,必须>0(单位分)。 + * 2、风险金额>=每个服务ID的风险金额上限。 * 3、当商户优惠字段为空时,付费项目总金额≤服务ID的风险金额上限 (未填写金额的付费项目,视为该付费项目金额为0)。 * 4、完结金额可大于、小于或等于风险金额。详细可见QA 关于订单风险金额问题 */ diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java index 1fcb04e..0fba9fa 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/TimeRange.java @@ -16,13 +16,20 @@ public class TimeRange { *

* 用户端展示用途。 * 用户下单时确认的服务开始时间(比如用户今天下单,明天开始接受服务,这里指的是明天的服务开始时间)。 + *

* 支持三种格式:yyyyMMddHHmmss、yyyyMMdd和 OnAccept + *

* ● 传入20091225091010表示2009年12月25日9点10分10秒。 + *

* ● 传入20091225默认认为时间为2009年12月25日 + *

* ● 传入OnAccept表示用户确认订单成功时间为【服务开始时间】。 + *

* 根据传入时间精准度进行校验 - * 1)若传入时间精准到秒,则校验精准到秒:【服务开始时间】>【商户调用创建订单接口时间 - * 2)若传入时间精准到日,则校验精准到日:【服务开始时间】>=【商户调用创建订单接口时间】 + *

+ * 1)若传入时间精准到秒,则校验精准到秒:【服务开始时间】>【商户调用创建订单接口时间 + *

+ * 2)若传入时间精准到日,则校验精准到日:【服务开始时间】>=【商户调用创建订单接口时间】 */ private String startTime; /** @@ -32,14 +39,21 @@ public class TimeRange { /** * 用户端展示用途,支持两种格式:yyyyMMddHHmmss和yyyyMMdd * ● 传入20091225091010表示2009年12月25日9点10分10秒。 + *

* ● 传入20091225默认认为时间为2009年12月25日 * 根据传入时间精准度进行校验 + *

* 1、若传入时间精准到秒,则校验精准到秒: - * 1)【预计服务结束时间】>【服务开始时间】 - * 2)【预计服务结束时间】>【商户调用接口时间+1分钟】 + *

+ * 1)【预计服务结束时间】>【服务开始时间】 + *

+ * 2)【预计服务结束时间】>【商户调用接口时间+1分钟】 + *

* 2、若传入时间精准到日,则校验精准到日: - * 1)【预计服务结束时间】>=【服务开始时间】 - * 2)【预计服务结束时间】>=【商户调用接口时间】 + *

+ * 1)【预计服务结束时间】>=【服务开始时间】 + *

+ * 2)【预计服务结束时间】>=【商户调用接口时间】 * 【建议】 * 1、用户下单时【未确定】服务结束时间,不填写。 * 2、用户下单时【已确定】服务结束时间,填写。 From c35df5a65af35ce204e96bc6ff2586dca3f4da8a Mon Sep 17 00:00:00 2001 From: dax Date: Wed, 16 Dec 2020 19:26:34 +0800 Subject: [PATCH 06/15] wechat pay score callback --- docs/README.md | 2 +- .../wechat/enumeration/WechatPayV3Type.java | 22 ++- .../payment/wechat/v3/WechatPayCallback.java | 171 +++++++++++++++--- .../payment/wechat/v3/WechatPayScoreApi.java | 164 +++++++++++++++++ .../DirectCompleteServiceOrderParams.java | 71 ++++++++ .../PayScoreUserConfirmConsumeData.java | 80 ++++++++ .../payscore/PayScoreUserPaidConsumeData.java | 87 +++++++++ .../v3/model/payscore/PaymentCollection.java | 74 ++++++++ .../payscore/PermissionsAuthCodeParams.java | 29 +++ .../payscore/PermissionsOpenIdParams.java | 35 ++++ .../v3/model/payscore/PromotionDetail.java | 93 ++++++++++ .../ServiceOrderPermissionParams.java | 34 ++++ 12 files changed, 827 insertions(+), 35 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java diff --git a/docs/README.md b/docs/README.md index 8134f5e..8ad18f7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -44,4 +44,4 @@ ## **免责声明** -**本项目涉及到资金交易,开发者需要经严格测试后方能用于生产环境,本项目不对使用者的行为负责。** \ No newline at end of file +**本项目涉及到资金交易开发,开发者需要经严格测试后方能用于生产环境,本项目不对使用者的行为负责。** \ No newline at end of file diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java index 7017f02..35c0c11 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/WechatPayV3Type.java @@ -10,6 +10,9 @@ import org.springframework.http.HttpMethod; * @since 1.0.0.RELEASE */ public enum WechatPayV3Type { + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** * 获取证书. * @@ -24,6 +27,8 @@ public enum WechatPayV3Type { */ FILE_DOWNLOAD(HttpMethod.GET, "%s/v3/billdownload/file"), + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** * 微信公众号支付或者小程序支付. * @@ -70,6 +75,8 @@ public enum WechatPayV3Type { */ TRANSACTION_OUT_TRADE_NO(HttpMethod.GET, "%s/v3/pay/transactions/out-trade-no/{out_trade_no}"), + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** * 合单下单-APP支付API. * @@ -109,24 +116,32 @@ public enum WechatPayV3Type { */ COMBINE_CLOSE(HttpMethod.POST, "%s/v3/combine-transactions/out-trade-no/{combine_out_trade_no}/close"), + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + /** * 商户预授权API. * * @since 1.0.2.RELEASE */ PAY_SCORE_PERMISSIONS(HttpMethod.POST, "%s/v3/payscore/permissions"), + /** + * 创单结单合并API. + * + * @since 1.0.2.RELEASE + */ + PAY_SCORE_DIRECT_COMPLETE(HttpMethod.POST, "%s/payscore/serviceorder/direct-complete"), /** * 查询与用户授权记录(授权协议号)API. * * @since 1.0.2.RELEASE */ - PAY_SCORE_QUEERY_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.GET, "%s/v3/payscore/permissions/authorization-code/{authorization_code}"), + PAY_SCORE_PERMISSIONS_AUTH_CODE(HttpMethod.GET, "%s/v3/payscore/permissions/authorization-code/{authorization_code}"), /** * 解除用户授权关系(授权协议号)API. * * @since 1.0.2.RELEASE */ - PAY_SCORE_TERMINATE_PERMISSIONS_AUTHORIZATION_CODE(HttpMethod.POST, "%s/v3/payscore/permissions/authorization-code/{authorization_code}/terminate"), + PAY_SCORE_TERMINATE_PERMISSIONS_AUTH_CODE(HttpMethod.POST, "%s/v3/payscore/permissions/authorization-code/{authorization_code}/terminate"), /** * 查询与用户授权记录(openid)API. * @@ -145,8 +160,6 @@ public enum WechatPayV3Type { * @since 1.0.2.RELEASE */ PAY_SCORE_USER_SERVICE_STATE(HttpMethod.GET, "%s/v3/payscore/user-service-state?service_id={service_id}&appid={appid}&openid={openid}"), - - /** * 创建支付分订单API * @@ -190,6 +203,7 @@ public enum WechatPayV3Type { */ PAY_SCORE_SYNC_USER_SERVICE_ORDER(HttpMethod.POST, "%s/v3/payscore/serviceorder/{out_order_no}/sync"), + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * 创建代金券批次API. diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java index 72bc8dc..2a15fb0 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java @@ -2,7 +2,10 @@ package cn.felord.payment.wechat.v3; import cn.felord.payment.PayException; import cn.felord.payment.wechat.v3.model.*; +import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserConfirmConsumeData; +import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPaidConsumeData; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import lombok.SneakyThrows; @@ -19,7 +22,7 @@ import java.util.function.Consumer; * 微信支付回调工具. *

* 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。 - * TODO 微信支付分有三个回调通知 + * * @author felord.cn * @since 1.0.0.RELEASE */ @@ -59,15 +62,16 @@ public class WechatPayCallback { /** * 微信支付代金券核销回调. * - * @param params the params - * @param couponConsumeDataConsumer the coupon consume data consumer + * @param params the params + * @param consumeDataConsumer the consume data consumer * @return the map + * @since 1.0.0.RELEASE */ @SneakyThrows - public Map couponCallback(ResponseSignVerifyParams params, Consumer couponConsumeDataConsumer) { - String data = callback(params, EventType.COUPON); + public Map couponCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.COUPON); CouponConsumeData couponConsumeData = MAPPER.readValue(data, CouponConsumeData.class); - couponConsumeDataConsumer.accept(couponConsumeData); + consumeDataConsumer.accept(couponConsumeData); Map responseBody = new HashMap<>(); responseBody.put("code", 200); responseBody.put("message", "SUCCESS"); @@ -80,15 +84,16 @@ public class WechatPayCallback { *

* 无需开发者判断,只有扣款成功微信才会回调此接口 * - * @param params the params - * @param transactionConsumeDataConsumer the transaction consume data consumer + * @param params the params + * @param consumeDataConsumer the consume data consumer * @return the map + * @since 1.0.0.RELEASE */ @SneakyThrows - public Map transactionCallback(ResponseSignVerifyParams params, Consumer transactionConsumeDataConsumer) { - String data = callback(params, EventType.TRANSACTION); + public Map transactionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.TRANSACTION); TransactionConsumeData transactionConsumeData = MAPPER.readValue(data, TransactionConsumeData.class); - transactionConsumeDataConsumer.accept(transactionConsumeData); + consumeDataConsumer.accept(transactionConsumeData); return Collections.singletonMap("code", "SUCCESS"); } @@ -98,21 +103,74 @@ public class WechatPayCallback { *

* 无需开发者判断,只有扣款成功微信才会回调此接口 * - * @param params the params - * @param combineTransactionConsumeDataConsumer the combine transaction consume data consumer + * @param params the params + * @param consumeDataConsumer the consume data consumer * @return the map + * @since 1.0.0.RELEASE */ @SneakyThrows - public Map combineTransactionCallback(ResponseSignVerifyParams params, Consumer combineTransactionConsumeDataConsumer) { - String data = callback(params, EventType.TRANSACTION); + public Map combineTransactionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.TRANSACTION); CombineTransactionConsumeData combineTransactionConsumeData = MAPPER.readValue(data, CombineTransactionConsumeData.class); - combineTransactionConsumeDataConsumer.accept(combineTransactionConsumeData); + consumeDataConsumer.accept(combineTransactionConsumeData); return Collections.singletonMap("code", "SUCCESS"); } + /** - * Callback string. + * 微信支付分确认订单回调通知. + *

+ * 该链接是通过商户[创建支付分订单]提交notify_url参数,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action” + * + * @param params the params + * @param consumeDataConsumer the consume data consumer + * @return the map + * @since 1.0.2.RELEASE + */ + @SneakyThrows + public Map payscoreUserConfirmCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.PAYSCORE_USER_CONFIRM); + PayScoreUserConfirmConsumeData payScoreUserConfirmConsumeData = MAPPER.readValue(data, PayScoreUserConfirmConsumeData.class); + consumeDataConsumer.accept(payScoreUserConfirmConsumeData); + return Collections.singletonMap("code", "SUCCESS"); + } + + /** + * 微信支付分支付成功回调通知API. + *

+ * 请求URL:该链接是通过商户[创建支付分订单]提交notify_url参数,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action” + * + * @param params the params + * @param consumeDataConsumer the consume data consumer + * @return the map + * @since 1.0.2.RELEASE + */ + @SneakyThrows + public Map payscoreUserPaidCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + String data = this.callback(params, EventType.PAYSCORE_USER_PAID); + PayScoreUserPaidConsumeData payScoreUserPaidConsumeData = MAPPER.readValue(data, PayScoreUserPaidConsumeData.class); + consumeDataConsumer.accept(payScoreUserPaidConsumeData); + return Collections.singletonMap("code", "SUCCESS"); + } + + /** + * Permission callback map. + * + * @param params the params + * @param consumeDataConsumer the consume data consumer + * @return the map + */ + @SneakyThrows + public Map permissionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + + + return Collections.singletonMap("code", "SUCCESS"); + } + + + /** + * Callback. * * @param params the params * @param eventType the event type @@ -120,24 +178,48 @@ public class WechatPayCallback { */ @SneakyThrows private String callback(ResponseSignVerifyParams params, EventType eventType) { - if (signatureProvider.responseSignVerify(params)) { - CallbackParams callbackParams = MAPPER.readValue(params.getBody(), CallbackParams.class); + CallbackParams callbackParams = resolve(params); - if (!Objects.equals(callbackParams.getEventType(), eventType.event)) { - log.error("wechat pay event type is not matched, callbackParams {}", callbackParams); - throw new PayException(" wechat pay event type is not matched"); - } - CallbackParams.Resource resource = callbackParams.getResource(); - String associatedData = resource.getAssociatedData(); - String nonce = resource.getNonce(); - String ciphertext = resource.getCiphertext(); - String data = signatureProvider.decryptResponseBody(tenantId, associatedData, nonce, ciphertext); - Assert.hasText(data, "decryptData is required"); - return data; + if (!Objects.equals(callbackParams.getEventType(), eventType.event)) { + log.error("wechat pay event type is not matched, callbackParams {}", callbackParams); + throw new PayException(" wechat pay event type is not matched"); + } + return decrypt(callbackParams); + } + + /** + * Resolve callback params. + * + * @param params the params + * @return the callback params + * @throws JsonProcessingException the json processing exception + * @since 1.0.2.RELEASE + */ + private CallbackParams resolve(ResponseSignVerifyParams params) throws JsonProcessingException { + if (signatureProvider.responseSignVerify(params)) { + return MAPPER.readValue(params.getBody(), CallbackParams.class); } throw new PayException("invalid wechat pay callback"); } + /** + * Decrypt. + * + * @param callbackParams the callback params + * @return the string + * @since 1.0.2.RELEASE + */ + private String decrypt(CallbackParams callbackParams) { + CallbackParams.Resource resource = callbackParams.getResource(); + String associatedData = resource.getAssociatedData(); + String nonce = resource.getNonce(); + String ciphertext = resource.getCiphertext(); + String data = signatureProvider.decryptResponseBody(tenantId, associatedData, nonce, ciphertext); + Assert.hasText(data, "decryptData is required"); + return data; + } + + /** * 事件类型用于处理回调. * @@ -145,12 +227,41 @@ public class WechatPayCallback { * @since 1.0.0.RELEASE */ enum EventType { + + /** + * 微信支付分确认订单事件. + * + * @since 1.0.2.RELEASE + */ + PAYSCORE_USER_CONFIRM("PAYSCORE.USER_CONFIRM"), + /** + * 微信支付分用户支付成功订单事件. + * + * @since 1.0.2.RELEASE + */ + PAYSCORE_USER_PAID("PAYSCORE.USER_PAID"), + /** + * 微信支付分授权事件. + * + * @since 1.0.2.RELEASE + */ + PAYSCORE_USER_OPEN("PAYSCORE.USER_CLOSE_SERVICE"), + /** + * 微信支付分解除授权事件. + * + * @since 1.0.2.RELEASE + */ + PAYSCORE_USER_CLOSE("PAYSCORE.USER_CLOSE_SERVICE"), /** * 优惠券核销事件. + * + * @since 1.0.0.RELEASE */ COUPON("COUPON.USE"), /** * 支付成功事件. + * + * @since 1.0.0.RELEASE */ TRANSACTION("TRANSACTION.SUCCESS"); diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java index c541967..325ed31 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -284,4 +284,168 @@ public class WechatPayScoreApi extends AbstractApi { .request(); return wechatResponseEntity; } + + /** + * 创单结单合并API + *

+ * 相对需确认模式,免确认模式减少了用户确认授权这步操作,因此在免确认模式下商户无法获取用户的授权状态,为了解决商户的困扰,我们为免确认模式特别提供了查询授权状态和调起授权页面的api接口,这些接口仅在免确认模式下需要调用,且必须调用。 + *

+ *

+ * 该接口适用于无需微信支付分做订单风控判断的业务场景,在服务完成后,通过该接口对用户进行免密代扣。 + *

+ * 注意: + * • 限制条件:【免确认订单模式】,用户已授权状态下,可调用该接口。 + *

+ *

+ * 特别提醒:创单结单合并接口暂未对外开放,如有需要请咨询对接的微信支付运营人员,申请开通调用权限。 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity directCompleteServiceOrder(DirectCompleteServiceOrderParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_DIRECT_COMPLETE, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + String notifyUrl = orderParams.getNotifyUrl(); + if (StringUtils.hasText(notifyUrl)) { + orderParams.setNotifyUrl(v3.getDomain().concat(notifyUrl)); + } + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 商户预授权API + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity permissions(ServiceOrderPermissionParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .toUri(); + + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + String notifyUrl = orderParams.getNotifyUrl(); + orderParams.setAppid(v3.getAppId()); + if (StringUtils.hasText(notifyUrl)) { + orderParams.setNotifyUrl(v3.getDomain().concat(notifyUrl)); + } + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + + /** + * 查询与用户授权记录(授权协议号)API + *

+ * 通过authorization_code,商户查询与用户授权关系 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity queryPermissionsByAuthCode(PermissionsAuthCodeParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_AUTH_CODE, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .queryParam("service_id", orderParams.getServiceId()) + .build() + .expand(orderParams.getAuthorizationCode()) + .toUri(); + + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 解除用户授权关系(授权协议号)API + *

+ * 通过authorization_code,商户解除用户授权关系 + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity terminatePermissionsByAuthCode(PermissionsAuthCodeParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_TERMINATE_PERMISSIONS_AUTH_CODE, params) + .function((wechatPayV3Type, orderParams) -> { + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getAuthorizationCode()) + .toUri(); + orderParams.setAuthorizationCode(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 查询与用户授权记录(openid)API + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity queryPermissionsByOpenId(PermissionsOpenIdParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_OPENID, params) + .function((wechatPayV3Type, orderParams) -> { + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .queryParam("appid", v3.getAppId()) + .queryParam("service_id", orderParams.getServiceId()) + .build() + .expand(orderParams.getOpenid()) + .toUri(); + return Get(uri); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } + + /** + * 解除用户授权关系(openid)API + * + * @param params the params + * @return the wechat response entity + */ + public WechatResponseEntity terminatePermissionsByOpenId(PermissionsOpenIdParams params) { + WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); + this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_OPENID, params) + .function((wechatPayV3Type, orderParams) -> { + + URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) + .build() + .expand(orderParams.getOpenid()) + .toUri(); + WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3(); + orderParams.setAppid(v3.getAppId()); + orderParams.setOpenid(null); + return Post(uri, orderParams); + }) + .consumer(wechatResponseEntity::convert) + .request(); + return wechatResponseEntity; + } } diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java new file mode 100644 index 0000000..94f2613 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/DirectCompleteServiceOrderParams.java @@ -0,0 +1,71 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +import java.util.List; + +/** + * 创单结单合并API请求参数 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class DirectCompleteServiceOrderParams { + /** + * The Appid. + */ + private String appid; + /** + * The Attach. + */ + private String attach; + /** + * The Goods tag. + */ + private String goodsTag; + /** + * The Location. + */ + private Location location; + /** + * The Notify url. + */ + private String notifyUrl; + /** + * The Openid. + */ + private String openid; + /** + * The Out order no. + */ + private String outOrderNo; + /** + * The Post discounts. + */ + private List postDiscounts; + /** + * The Post payments. + */ + private List postPayments; + /** + * The Profit sharing. + */ + private Boolean profitSharing; + /** + * The Service id. + */ + private String serviceId; + /** + * The Service introduction. + */ + private String serviceIntroduction; + /** + * The Time range. + */ + private TimeRange timeRange; + /** + * The Total amount. + */ + private Long totalAmount; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java new file mode 100644 index 0000000..56625fb --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserConfirmConsumeData.java @@ -0,0 +1,80 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +import java.util.List; + +/** + * 微信支付分用户确认订单回调解密. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PayScoreUserConfirmConsumeData { + + /** + * The Appid. + */ + private String appid; + /** + * The Attach. + */ + private String attach; + /** + * The Location. + */ + private Location location; + /** + * The Mchid. + */ + private String mchid; + /** + * The Openid. + */ + private String openid; + /** + * The Order id. + */ + private String orderId; + /** + * The Out order no. + */ + private String outOrderNo; + /** + * The Post discounts. + */ + private List postDiscounts; + /** + * The Post payments. + */ + private List postPayments; + /** + * The Risk fund. + */ + private RiskFund riskFund; + /** + * The Service id. + */ + private String serviceId; + /** + * The Service introduction. + */ + private String serviceIntroduction; + /** + * The State. + */ + private String state; + /** + * The State description. + */ + private String stateDescription; + /** + * The Time range. + */ + private TimeRange timeRange; + /** + * The Total amount. + */ + private String totalAmount; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java new file mode 100644 index 0000000..9f6e6d1 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPaidConsumeData.java @@ -0,0 +1,87 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +import java.util.List; + +/** + * 微信支付分支付成功回调解密 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PayScoreUserPaidConsumeData { + /** + * The Appid. + */ + private String appid; + /** + * The Attach. + */ + private String attach; + /** + * The Collection. + */ + private PaymentCollection collection; + /** + * The Location. + */ + private Location location; + /** + * The Mchid. + */ + private String mchid; + /** + * The Need collection. + */ + private Boolean needCollection; + /** + * The Notify url. + */ + private String notifyUrl; + /** + * The Openid. + */ + private String openid; + /** + * The Order id. + */ + private String orderId; + /** + * The Out order no. + */ + private String outOrderNo; + /** + * The Post discounts. + */ + private List postDiscounts; + /** + * The Post payments. + */ + private List postPayments; + /** + * The Risk fund. + */ + private RiskFund riskFund; + /** + * The Service id. + */ + private String serviceId; + /** + * The Service introduction. + */ + private String serviceIntroduction; + /** + * The State. + */ + private String state; + /** + * The Time range. + */ + private TimeRange timeRange; + /** + * The Total amount. + */ + private String totalAmount; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java new file mode 100644 index 0000000..924ae7f --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PaymentCollection.java @@ -0,0 +1,74 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +import java.util.List; + +/** + * 微信支付分支付成功回调,收款信息,非0元完结后返回 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PaymentCollection { + + /** + * The Details. + */ + private List details; + /** + * The Paid amount. + */ + private Long paidAmount; + /** + * The Paying amount. + */ + private Long payingAmount; + /** + * The State. + */ + private String state; + /** + * The Total amount. + */ + private Long totalAmount; + + /** + * 收款明细列表 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ + @Data + public static class Detail { + + /** + * The Amount. + */ + private Long amount; + /** + * The Paid time. + */ + private String paidTime; + /** + * The Paid type. + */ + private String paidType; + /** + * The Promotion detail. + */ + private List promotionDetail; + /** + * The Seq. + */ + private Long seq; + /** + * The Transaction id. + */ + private String transactionId; + + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java new file mode 100644 index 0000000..e531903 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsAuthCodeParams.java @@ -0,0 +1,29 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 适用于以下API: + *

+ * 查询与用户授权记录(授权协议号)API + *

+ * 解除用户授权关系(授权协议号)API + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PermissionsAuthCodeParams { + /** + * 服务ID,必填 + */ + private String serviceId; + /** + * 授权协议号,必填 + */ + private String authorizationCode; + /** + * 仅仅适用于解除用户授权关系(授权协议号)API + */ + private String reason; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java new file mode 100644 index 0000000..2497484 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PermissionsOpenIdParams.java @@ -0,0 +1,35 @@ +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 适用于以下API: + *

+ * 查询与用户授权记录(openid)API + *

+ * 解除用户授权关系(openid)API + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PermissionsOpenIdParams { + /** + * openid,必填 + */ + private String openid; + /** + * 仅仅适用于解除用户授权关系(openid)API + */ + private String appid; + /** + * 服务ID,必填 + *

+ * 该服务ID有本接口对应产品的权限。 + */ + private String serviceId; + /** + * 仅仅适用于解除用户授权关系(openid)API + */ + private String reason; +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java new file mode 100644 index 0000000..c513ed7 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PromotionDetail.java @@ -0,0 +1,93 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +import java.util.List; + +/** + * 微信支付分支付成功回调,优惠功能 + * + * 注:针对2020年5月27日10:00:00以后完结的订单生效 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PromotionDetail { + + /** + * The Amount. + */ + private Long amount; + /** + * The Coupon id. + */ + private String couponId; + /** + * The Currency. + */ + private String currency; + /** + * The Goods detail. + */ + private List goodsDetail; + /** + * The Merchant contribute. + */ + private Long merchantContribute; + /** + * The Name. + */ + private String name; + /** + * The Other contribute. + */ + private Long otherContribute; + /** + * The Scope. + */ + private String scope; + /** + * The Stock id. + */ + private String stockId; + /** + * The Type. + */ + private String type; + /** + * The Wechatpay contribute. + */ + private Long wechatpayContribute; + + /** + * The type Goods detail. + */ + @Data + public static class GoodsDetail { + + /** + * The Discount amount. + */ + private Long discountAmount; + /** + * The Goods id. + */ + private String goodsId; + /** + * The Goods remark. + */ + private String goodsRemark; + /** + * The Quantity. + */ + private Long quantity; + /** + * The Unit price. + */ + private Long unitPrice; + + } +} diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java new file mode 100644 index 0000000..c6d9e96 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/ServiceOrderPermissionParams.java @@ -0,0 +1,34 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + +import lombok.Data; + +/** + * 商户预授权API请求参数 + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class ServiceOrderPermissionParams { + + /** + * 服务id,必填 + */ + private String serviceId; + /** + * 服务商申请的公众号或移动应用APPID,必填 + */ + private String appid; + /** + * 授权协议号,必填 + *

+ * 预授权成功时的授权协议号,要求此参数只能由数字、大小写字母_-*组成,且在同一个商户号下唯一。详见[商户订单号]。 + */ + private String authorizationCode; + /** + * 商户接收授权回调通知的地址,选填 + */ + private String notifyUrl; + +} From 73e2b3078ebef8557ef1b39d62e47d8333d19516 Mon Sep 17 00:00:00 2001 From: dax Date: Thu, 17 Dec 2020 11:46:01 +0800 Subject: [PATCH 07/15] =?UTF-8?q?=E6=8E=88=E6=9D=83/=E8=A7=A3=E9=99=A4?= =?UTF-8?q?=E6=8E=88=E6=9D=83=E6=9C=8D=E5=8A=A1=E5=9B=9E=E8=B0=83=E9=80=9A?= =?UTF-8?q?=E7=9F=A5API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../payment/wechat/v3/WechatPayCallback.java | 31 ++++++++--- .../payment/wechat/v3/WechatPayScoreApi.java | 2 +- .../PayScoreUserPermissionConsumeData.java | 53 +++++++++++++++++++ 3 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPermissionConsumeData.java diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java index 2a15fb0..62301c6 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayCallback.java @@ -4,6 +4,7 @@ import cn.felord.payment.PayException; import cn.felord.payment.wechat.v3.model.*; import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserConfirmConsumeData; import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPaidConsumeData; +import cn.felord.payment.wechat.v3.model.payscore.PayScoreUserPermissionConsumeData; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -155,16 +156,34 @@ public class WechatPayCallback { } /** - * Permission callback map. + * 授权/解除授权服务回调通知API. + *

+ * 微信支付分通过授权/解除授权服务通知接口将用户过授权/解除授权服务消息通知给商户 + *

+ * 普通授权模式是通过[商户入驻配置申请表]提交service_notify_url设置,预授权模式是通过[商户预授权]提交的notify_url设置,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。 通知url必须为直接可访问的url,不能携带参数。示例: “https://pay.weixin.qq.com/wxpay/pay.action” * * @param params the params * @param consumeDataConsumer the consume data consumer * @return the map */ @SneakyThrows - public Map permissionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { - + public Map permissionCallback(ResponseSignVerifyParams params, Consumer consumeDataConsumer) { + CallbackParams callbackParams = resolve(params); + String eventType = callbackParams.getEventType(); + boolean closed; + if (Objects.equals(eventType, EventType.PAYSCORE_USER_OPEN.event)) { + closed = false; + } else if (Objects.equals(eventType, EventType.PAYSCORE_USER_CLOSE.event)) { + closed = true; + } else { + log.error("wechat pay event type is not matched, callbackParams {}", callbackParams); + throw new PayException(" wechat pay event type is not matched"); + } + String data = this.decrypt(callbackParams); + PayScoreUserPermissionConsumeData payScoreUserPermissionConsumeData = MAPPER.readValue(data, PayScoreUserPermissionConsumeData.class); + payScoreUserPermissionConsumeData.setClosed(closed); + consumeDataConsumer.accept(payScoreUserPermissionConsumeData); return Collections.singletonMap("code", "SUCCESS"); } @@ -178,13 +197,13 @@ public class WechatPayCallback { */ @SneakyThrows private String callback(ResponseSignVerifyParams params, EventType eventType) { - CallbackParams callbackParams = resolve(params); + CallbackParams callbackParams = this.resolve(params); if (!Objects.equals(callbackParams.getEventType(), eventType.event)) { log.error("wechat pay event type is not matched, callbackParams {}", callbackParams); throw new PayException(" wechat pay event type is not matched"); } - return decrypt(callbackParams); + return this.decrypt(callbackParams); } /** @@ -245,7 +264,7 @@ public class WechatPayCallback { * * @since 1.0.2.RELEASE */ - PAYSCORE_USER_OPEN("PAYSCORE.USER_CLOSE_SERVICE"), + PAYSCORE_USER_OPEN("PAYSCORE.USER_OPEN_SERVICE"), /** * 微信支付分解除授权事件. * diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java index 9296a46..f099642 100644 --- a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatPayScoreApi.java @@ -432,7 +432,7 @@ public class WechatPayScoreApi extends AbstractApi { */ public WechatResponseEntity terminatePermissionsByOpenId(PermissionsOpenIdParams params) { WechatResponseEntity wechatResponseEntity = new WechatResponseEntity<>(); - this.client().withType(WechatPayV3Type.PAY_SCORE_PERMISSIONS_OPENID, params) + this.client().withType(WechatPayV3Type.PAY_SCORE_TERMINATE_PERMISSIONS_OPENID, params) .function((wechatPayV3Type, orderParams) -> { URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA)) diff --git a/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPermissionConsumeData.java b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPermissionConsumeData.java new file mode 100644 index 0000000..0164950 --- /dev/null +++ b/payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/payscore/PayScoreUserPermissionConsumeData.java @@ -0,0 +1,53 @@ + +package cn.felord.payment.wechat.v3.model.payscore; + + +import lombok.Data; + +/** + * 授权、解除授权服务回调解密. + * + * @author felord.cn + * @since 1.0.2.RELEASE + */ +@Data +public class PayScoreUserPermissionConsumeData { + + /** + * 是否是解除授权,此参数并非微信返回参数 + * + * 是:true,不是:false + * + * 用来判断是授权还是解除授权 + */ + private boolean closed; + /** + * The Appid. + */ + private String appid; + /** + * The Mchid. + */ + private String mchid; + /** + * The Openid. + */ + private String openid; + /** + * The Openorclose time. + */ + private String openorcloseTime; + /** + * 只在 微信支付分授权回调中返回 + */ + private String outRequestNo; + /** + * The Service id. + */ + private String serviceId; + /** + * The User service status. + */ + private String userServiceStatus; + +} From 84a4716d43eef4c3962af438889508a86eda8038 Mon Sep 17 00:00:00 2001 From: dax Date: Thu, 17 Dec 2020 19:18:36 +0800 Subject: [PATCH 08/15] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=85=88=E4=BA=AB?= =?UTF-8?q?=E5=8D=A1API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eTransactionConsumeData.CombineAmount.html | 2 +- ...ansactionConsumeData.SubOrderCallback.html | 2 +- .../model/CombineTransactionConsumeData.html | 2 +- ...eTransactionConsumeData.CombineAmount.html | 6 +- ...ansactionConsumeData.SubOrderCallback.html | 6 +- .../CombineTransactionConsumeData.html | 4 +- .../wechat/enumeration/ContractStatus.java | 28 +++ .../wechat/enumeration/WechatPayV3Type.java | 21 +++ .../payment/wechat/v3/WechatApiProvider.java | 13 +- .../wechat/v3/WechatDiscountCardApi.java | 102 +++++++++++ .../payment/wechat/v3/WechatPayCallback.java | 74 ++++++-- .../wechat/v3/model/CouponConsumeData.java | 71 ++++++- .../payment/wechat/v3/model/SettleInfo.java | 4 +- .../v3/model/TransactionConsumeData.java | 16 +- .../CombineTransactionConsumeData.java | 10 +- .../DiscountCardAcceptedConsumeData.java | 173 ++++++++++++++++++ .../DiscountCardPreRequestParams.java | 33 ++++ .../model/discountcard/UserRecordsParams.java | 134 ++++++++++++++ 18 files changed, 656 insertions(+), 45 deletions(-) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/enumeration/ContractStatus.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/WechatDiscountCardApi.java rename payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/{ => combine}/CombineTransactionConsumeData.java (88%) create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/discountcard/DiscountCardAcceptedConsumeData.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/discountcard/DiscountCardPreRequestParams.java create mode 100644 payment-spring-boot-autoconfigure/src/main/java/cn/felord/payment/wechat/v3/model/discountcard/UserRecordsParams.java diff --git a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.CombineAmount.html b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.CombineAmount.html index c63c478..c49effd 100644 --- a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.CombineAmount.html +++ b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.CombineAmount.html @@ -95,7 +95,7 @@

  • java.lang.Object
  • diff --git a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.SubOrderCallback.html b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.SubOrderCallback.html index 027f3d2..48946f1 100644 --- a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.SubOrderCallback.html +++ b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.SubOrderCallback.html @@ -95,7 +95,7 @@
  • java.lang.Object
  • diff --git a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.html b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.html index d035156..741c243 100644 --- a/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.html +++ b/docs/apidocs/cn/felord/payment/wechat/v3/model/CombineTransactionConsumeData.html @@ -95,7 +95,7 @@
  • java.lang.Object
  • diff --git a/docs/apidocs/cn/felord/payment/wechat/v3/model/class-use/CombineTransactionConsumeData.CombineAmount.html b/docs/apidocs/cn/felord/payment/wechat/v3/model/class-use/CombineTransactionConsumeData.CombineAmount.html index ff4fa42..e564ea7 100644 --- a/docs/apidocs/cn/felord/payment/wechat/v3/model/class-use/CombineTransactionConsumeData.CombineAmount.html +++ b/docs/apidocs/cn/felord/payment/wechat/v3/model/class-use/CombineTransactionConsumeData.CombineAmount.html @@ -4,7 +4,7 @@ -类 cn.felord.payment.wechat.v3.model.CombineTransactionConsumeData.CombineAmount的使用 (payment-spring-boot 1.0.0.RELEASE API) +类 cn.felord.payment.wechat.v3.model.combine.CombineTransactionConsumeData.CombineAmount的使用 (payment-spring-boot 1.0.0.RELEASE API) @@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@