mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
feat: 实现支付分停车服务API
- 查询车牌服务开通信息API - 创建停车入场API - 扣费受理API - 查询订单API - 停车入场状态变更通知API - 订单支付结果通知API
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.enumeration;
|
||||
/**
|
||||
* 车牌颜色枚举
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
public enum PlateColor {
|
||||
/**
|
||||
* 蓝色
|
||||
*/
|
||||
BLUE,
|
||||
/**
|
||||
* 绿色
|
||||
*/
|
||||
GREEN,
|
||||
/**
|
||||
* 黄色
|
||||
*/
|
||||
YELLOW,
|
||||
/**
|
||||
* 黑色
|
||||
*/
|
||||
BLACK,
|
||||
/**
|
||||
* 白色
|
||||
*/
|
||||
WHITE,
|
||||
/**
|
||||
* 黄绿色
|
||||
*/
|
||||
LIMEGREEN
|
||||
}
|
||||
@@ -195,7 +195,7 @@ public enum WechatPayV3Type {
|
||||
*/
|
||||
PAY_SCORE_TERMINATE_PERMISSIONS_OPENID(HttpMethod.POST, "%s/v3/payscore/permissions/openid/{openid}/terminate"),
|
||||
/**
|
||||
* 查询用户授权状态API.
|
||||
* 查询用户授权状态API(旧版接口).
|
||||
*
|
||||
* @since 1.0.2.RELEASE
|
||||
*/
|
||||
@@ -248,8 +248,30 @@ public enum WechatPayV3Type {
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAY_SCORE_MERCHANT_BILL(HttpMethod.GET, "%s/v3/payscore/merchant-bill"),
|
||||
|
||||
|
||||
/**
|
||||
* 查询车牌服务开通信息API
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAY_SCORE_PARKING_FIND(HttpMethod.GET, "%s/v3/vehicle/parking/services/find"),
|
||||
/**
|
||||
* 创建停车入场API
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAY_SCORE_PARKING_PARKINGS(HttpMethod.POST, "%s/v3/vehicle/parking/parkings"),
|
||||
/**
|
||||
* 扣费受理API
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAY_SCORE_PARKING_TRANSACTIONS_PARKINGS(HttpMethod.POST, "%s/v3/vehicle/transactions/parking"),
|
||||
/**
|
||||
* 查询订单API
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAY_SCORE_PARKING_TRANSACTIONS_OUTTRADENO(HttpMethod.GET, "%s/v3/vehicle/transactions/out-trade-no/{out_trade_no}"),
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,6 +100,17 @@ public class WechatApiProvider {
|
||||
return new WechatPayScoreApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分停车服务.
|
||||
*
|
||||
* @param tenantId the tenant id
|
||||
* @return the wechat pay score parking api
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
public WechatPayScoreParkingApi payScoreParkingApi(String tenantId) {
|
||||
return new WechatPayScoreParkingApi(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付先享卡.
|
||||
*
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
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.CallbackParams;
|
||||
import cn.felord.payment.wechat.v3.model.CouponConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.ProfitSharingConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.RefundConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams;
|
||||
import cn.felord.payment.wechat.v3.model.TransactionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.busifavor.BusiFavorReceiveConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.combine.CombineTransactionConsumeData;
|
||||
import cn.felord.payment.wechat.v3.model.discountcard.DiscountCardAcceptedConsumeData;
|
||||
@@ -29,6 +34,8 @@ import cn.felord.payment.wechat.v3.model.payscore.PayScoreConsumer;
|
||||
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 cn.felord.payment.wechat.v3.model.payscore.parking.ParkingCallback;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.TransParkingCallback;
|
||||
import cn.felord.payment.wechat.v3.model.profitsharing.ProfitsharingConsumeData;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -101,7 +108,7 @@ public class WechatPayCallback {
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> profitSharingCallback(ResponseSignVerifyParams params, Consumer<ProfitSharingConsumeData> consumeDataConsumer) {
|
||||
String data = this.callback(params, EventType.TRANSACTION);
|
||||
String data = this.callback(params, EventType.TRANSACTION_SUCCESS);
|
||||
ProfitSharingConsumeData consumeData = MAPPER.readValue(data, ProfitSharingConsumeData.class);
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
@@ -138,7 +145,7 @@ public class WechatPayCallback {
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> transactionCallback(ResponseSignVerifyParams params, Consumer<TransactionConsumeData> consumeDataConsumer) {
|
||||
String data = this.callback(params, EventType.TRANSACTION);
|
||||
String data = this.callback(params, EventType.TRANSACTION_SUCCESS);
|
||||
TransactionConsumeData consumeData = MAPPER.readValue(data, TransactionConsumeData.class);
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
@@ -156,7 +163,7 @@ public class WechatPayCallback {
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> combineTransactionCallback(ResponseSignVerifyParams params, Consumer<CombineTransactionConsumeData> consumeDataConsumer) {
|
||||
String data = this.callback(params, EventType.TRANSACTION);
|
||||
String data = this.callback(params, EventType.TRANSACTION_SUCCESS);
|
||||
CombineTransactionConsumeData consumeData = MAPPER.readValue(data, CombineTransactionConsumeData.class);
|
||||
consumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
@@ -192,6 +199,73 @@ public class WechatPayCallback {
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付分停车入场状态变更通知.
|
||||
* <p>
|
||||
* 从用户进入开通微信支付分停车服务的停车场(用户入场通知接口),到用户离场期间(扣款接口),
|
||||
* 这个时间段内如果停车入场状态变为可用或者不可用,微信会把相关状态变更情况(可用/不可用)异步发送给商户,
|
||||
* 回调url为调用用户入场通知接口时填写的notify_url字段。
|
||||
* 商户在收到停车入场状态变更通知后,需进行接收处理并返回应答。
|
||||
*
|
||||
* @param params the params
|
||||
* @param parkingCallbackConsumer the parking callback consumer
|
||||
* @return the map
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> payscoreParkingCallback(ResponseSignVerifyParams params, Consumer<ParkingCallback> parkingCallbackConsumer) {
|
||||
CallbackParams callbackParams = resolve(params);
|
||||
String eventType = callbackParams.getEventType();
|
||||
if (Objects.equals(eventType, EventType.PAYSCORE_PARKING_ENTRANCE_STATE_CHANGE.event)) {
|
||||
String data = this.decrypt(callbackParams);
|
||||
ParkingCallback parkingCallback = MAPPER.readValue(data, ParkingCallback.class);
|
||||
parkingCallbackConsumer.accept(parkingCallback);
|
||||
} else {
|
||||
log.error("wechat pay event type is not matched, callbackParams {}", callbackParams);
|
||||
throw new PayException(" wechat pay event type is not matched");
|
||||
}
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付分停车订单支付结果通知
|
||||
* <p>
|
||||
* 商户请求微信支付分停车服务扣费受理接口,会完成订单受理。
|
||||
* 订单实际支付完成后,微信支付会把订单支付结果信息发送给商户,商户需要接收处理,并返回应答。
|
||||
* 同时,如果由于用户余额不足等原因,微信支付会进行垫资,用户对该垫资单进行了还款以后,微信支付会把该笔订单还款信息通知到商户。
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
|
||||
* 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。
|
||||
* 如果未处理,则再进行处理;如果已处理,则直接返回结果成功。
|
||||
* 在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。</li>
|
||||
* <li>如果在所有通知频率后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。</li>
|
||||
* </ul>
|
||||
* 特别提醒:商户系统对于支付成功通知的内容一定要做签名验证,并校验通知的信息是否与商户侧的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。
|
||||
* @param params the params
|
||||
* @param transParkingCallbackConsumer the transParkingCallbackConsumer
|
||||
* @return the map
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> payscoreTransParkingCallback(ResponseSignVerifyParams params, Consumer<TransParkingCallback> transParkingCallbackConsumer) {
|
||||
CallbackParams callbackParams = resolve(params);
|
||||
String eventType = callbackParams.getEventType();
|
||||
if (Objects.equals(eventType, EventType.TRANSACTION_SUCCESS.event) ||
|
||||
Objects.equals(eventType, EventType.TRANSACTION_FAIL.event) ||
|
||||
Objects.equals(eventType, EventType.TRANSACTION_PAY_BACK.event)
|
||||
) {
|
||||
String data = this.decrypt(callbackParams);
|
||||
TransParkingCallback transParkingCallback = MAPPER.readValue(data, TransParkingCallback.class);
|
||||
transParkingCallbackConsumer.accept(transParkingCallback);
|
||||
} else {
|
||||
log.error("wechat pay event type is not matched, callbackParams {}", callbackParams);
|
||||
throw new PayException(" wechat pay event type is not matched");
|
||||
}
|
||||
return response();
|
||||
}
|
||||
|
||||
/**
|
||||
* 授权/解除授权服务回调通知API.
|
||||
* <p>
|
||||
@@ -322,7 +396,7 @@ public class WechatPayCallback {
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> profitsharingCallback(ResponseSignVerifyParams params, Consumer<ProfitsharingConsumeData> profitsharingConsumeDataConsumer) {
|
||||
String callback = this.callback(params, EventType.TRANSACTION);
|
||||
String callback = this.callback(params, EventType.TRANSACTION_SUCCESS);
|
||||
ProfitsharingConsumeData consumeData = MAPPER.readValue(callback, ProfitsharingConsumeData.class);
|
||||
profitsharingConsumeDataConsumer.accept(consumeData);
|
||||
return response();
|
||||
@@ -426,6 +500,12 @@ public class WechatPayCallback {
|
||||
* @since 1.0.2.RELEASE
|
||||
*/
|
||||
PAYSCORE_USER_CLOSE("PAYSCORE.USER_CLOSE_SERVICE"),
|
||||
/**
|
||||
* 停车入场状态变更通知事件.
|
||||
*
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
PAYSCORE_PARKING_ENTRANCE_STATE_CHANGE("VEHICLE.ENTRANCE_STATE_CHANGE"),
|
||||
|
||||
/**
|
||||
* 用户领取微信先享卡事件.
|
||||
@@ -467,11 +547,19 @@ public class WechatPayCallback {
|
||||
COUPON_SEND("COUPON.SEND"),
|
||||
|
||||
/**
|
||||
* 支付成功、分账、分账回退事件.
|
||||
* 支付成功、支付分停车支付成功、分账、分账回退事件.
|
||||
*
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
TRANSACTION("TRANSACTION.SUCCESS"),
|
||||
TRANSACTION_SUCCESS("TRANSACTION.SUCCESS"),
|
||||
/**
|
||||
* 支付分停车支付失败通知
|
||||
*/
|
||||
TRANSACTION_FAIL("TRANSACTION.FAIL"),
|
||||
/**
|
||||
* 支付分停车还款通知
|
||||
*/
|
||||
TRANSACTION_PAY_BACK("TRANSACTION.PAY_BACK"),
|
||||
|
||||
/**
|
||||
* 退款成功事件.
|
||||
|
||||
@@ -53,7 +53,7 @@ public class WechatPayScoreApi extends AbstractApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分-查询用户授权状态API.
|
||||
* 微信支付分-查询用户授权状态API(旧版接口).
|
||||
* <p>
|
||||
* 免确认订单起始接口,【免确认订单模式】是高级接口权限,参见:<a href="https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/payscore/chapter2_5.shtml">业务流程说明</a>
|
||||
* <p>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2019-2022 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
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.ResponseSignVerifyParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingServiceQueryParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.ParkingParams;
|
||||
import cn.felord.payment.wechat.v3.model.payscore.parking.TransParkingParams;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 微信支付分停车服务API.
|
||||
* <p>
|
||||
* 详细文档,参见 <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter3_7_1.shtml">微信支付分停车服务介绍</a>
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
public class WechatPayScoreParkingApi extends AbstractApi {
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract api.
|
||||
*
|
||||
* @param wechatPayClient the wechat pay client
|
||||
* @param tenantId the tenant id
|
||||
*/
|
||||
public WechatPayScoreParkingApi(WechatPayClient wechatPayClient, String tenantId) {
|
||||
super(wechatPayClient, tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分-查询车牌服务开通信息API
|
||||
* <p>
|
||||
* 该接口仅支持停车场景,商户首先请求查询车牌服务开通信息接口,确认该车牌,是否被该用户开通车主服务。
|
||||
*
|
||||
* @param params the params
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> find(ParkingServiceQueryParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PARKING_FIND, params)
|
||||
.function((wechatPayV3Type, parkingServiceQueryParams) -> {
|
||||
|
||||
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
|
||||
queryParams.add("appid", parkingServiceQueryParams.getAppid());
|
||||
queryParams.add("plate_number", parkingServiceQueryParams.getPlateNumber());
|
||||
queryParams.add("plate_color", parkingServiceQueryParams.getPlateColor().name());
|
||||
queryParams.add("openid", parkingServiceQueryParams.getOpenid());
|
||||
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.queryParams(queryParams)
|
||||
.build()
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分-创建停车入场API
|
||||
* <p>
|
||||
* 车辆入场以后,商户调用该接口,创建停车入场信息,需要处理回调逻辑。
|
||||
* <p>
|
||||
* 回调通知 {@link WechatPayCallback#payscoreParkingCallback(ResponseSignVerifyParams, Consumer)}
|
||||
* @param params the params
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> parking(ParkingParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PARKING_PARKINGS, params)
|
||||
.function((wechatPayV3Type, parkingParams) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
parkingParams.setNotifyUrl(v3.getDomain().concat(parkingParams.getNotifyUrl()));
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, parkingParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付分-扣费受理API
|
||||
* <p>
|
||||
* 商户请求扣费受理接口,会完成订单受理。微信支付进行异步扣款,支付完成后,会将订单支付结果发送给商户。
|
||||
* <p>
|
||||
* 注意:
|
||||
* <ul>
|
||||
* <li>必须确认扣费受理接口的交易状态返回{@code ACCEPTED}才能放行车辆,若未接收到该状态而放行车辆离场,造成的资金损失由商户侧自行承担</li>
|
||||
* </ul>
|
||||
* 回调通知 {@link WechatPayCallback#payscoreTransParkingCallback(ResponseSignVerifyParams, Consumer)}
|
||||
* @param params the params
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> transactionsParking(TransParkingParams params) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PARKING_TRANSACTIONS_PARKINGS, params)
|
||||
.function((wechatPayV3Type, transParkingParams) -> {
|
||||
WechatPayProperties.V3 v3 = this.wechatMetaBean().getV3();
|
||||
transParkingParams.setNotifyUrl(v3.getDomain().concat(transParkingParams.getNotifyUrl()));
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.toUri();
|
||||
return Post(uri, transParkingParams);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单API.
|
||||
*
|
||||
* @param outTradeNo the out trade no
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> queryTransactionByOutTradeNo(String outTradeNo) {
|
||||
WechatResponseEntity<ObjectNode> wechatResponseEntity = new WechatResponseEntity<>();
|
||||
this.client().withType(WechatPayV3Type.PAY_SCORE_PARKING_TRANSACTIONS_OUTTRADENO, outTradeNo)
|
||||
.function((wechatPayV3Type, tradeNo) -> {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(wechatPayV3Type.uri(WeChatServer.CHINA))
|
||||
.build()
|
||||
.expand(tradeNo)
|
||||
.toUri();
|
||||
return Get(uri);
|
||||
})
|
||||
.consumer(wechatResponseEntity::convert)
|
||||
.request();
|
||||
return wechatResponseEntity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.PlateColor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* 创建停车入场API回调结果
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class ParkingCallback {
|
||||
|
||||
/**
|
||||
* 调用接口提交的商户号
|
||||
*/
|
||||
private String spMchid;
|
||||
/**
|
||||
* 停车入场id
|
||||
* <p>
|
||||
* 微信支付分停车服务为商户分配的入场id,商户通过入场通知接口获取入场id
|
||||
*/
|
||||
private String parkingId;
|
||||
/**
|
||||
* 商户侧入场标识id,在同一个商户号下唯一
|
||||
*/
|
||||
private String outParkingNo;
|
||||
/**
|
||||
* 车牌号
|
||||
* <p>
|
||||
* 仅包括省份+车牌,不包括特殊字符,示例值:粤B888888
|
||||
*/
|
||||
private String plateNumber;
|
||||
/**
|
||||
* 车牌颜色
|
||||
*/
|
||||
private PlateColor plateColor;
|
||||
/**
|
||||
* 入场时间
|
||||
* <p>
|
||||
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private OffsetDateTime startTime;
|
||||
/**
|
||||
* 停车场名称
|
||||
*/
|
||||
private String parkingName;
|
||||
/**
|
||||
* 免费时长
|
||||
* <p>
|
||||
* 单位:秒
|
||||
*/
|
||||
private Integer freeDuration;
|
||||
/**
|
||||
* 本次入场车牌的服务状态
|
||||
* <ul>
|
||||
* <li>NORMAL:正常状态,可以使用车主服务</li>
|
||||
* <li>BLOCKED:不可用状态,暂时不可以使用车主服务</li>
|
||||
* </ul>
|
||||
*/
|
||||
private String parkingState;
|
||||
/**
|
||||
* 不可用服务状态描述,返回车牌状态为{@code BLOCKED},会返回该字段,描述具体的原因
|
||||
* <p>
|
||||
* 不可用状态:
|
||||
* <ul>
|
||||
* <li>PAUSE:已暂停车主服务</li>
|
||||
* <li>OVERDUE:已授权签约但欠费,不能提供服务,商户提示用户进行还款</li>
|
||||
* <li>REMOVE:用户移除车牌导致车牌不可用。请跳转到授权/开通接口</li>
|
||||
* </ul>
|
||||
*/
|
||||
private String blockedStateDescription;
|
||||
/**
|
||||
* 状态变更时间
|
||||
* <p>
|
||||
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private OffsetDateTime stateUpdateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.PlateColor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
/**
|
||||
* 停车场景信息
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class ParkingInfo {
|
||||
/**
|
||||
* 停车入场id,必传
|
||||
* <p>
|
||||
* 微信支付分停车服务为商户分配的入场id,商户通过入场通知接口获取入场id
|
||||
*/
|
||||
private String parkingId;
|
||||
/**
|
||||
* 车牌号,必传
|
||||
* <p>
|
||||
* 仅包括省份+车牌,不包括特殊字符,示例值:粤B888888
|
||||
*/
|
||||
private String plateNumber;
|
||||
/**
|
||||
* 车牌颜色,必传
|
||||
*/
|
||||
private PlateColor plateColor;
|
||||
/**
|
||||
* 入场时间,必传
|
||||
* <p>
|
||||
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private OffsetDateTime startTime;
|
||||
/**
|
||||
* 出场时间,必传
|
||||
* <p>
|
||||
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private OffsetDateTime endTime;
|
||||
/**
|
||||
* 停车场名称,必传
|
||||
*/
|
||||
private String parkingName;
|
||||
/**
|
||||
* 计费时长,必传
|
||||
* <p>
|
||||
* 单位:秒
|
||||
*/
|
||||
private Integer chargingDuration;
|
||||
/**
|
||||
* 停车场设备id,必传
|
||||
*/
|
||||
private String deviceId;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.PlateColor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* 创建停车入场API参数
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class ParkingParams {
|
||||
/**
|
||||
* 商户入场id,必传
|
||||
* <p>
|
||||
* 商户侧入场标识id,在同一个商户号下唯一
|
||||
*/
|
||||
private String outParkingNo;
|
||||
/**
|
||||
* 车牌号,必传
|
||||
* <p>
|
||||
* 仅包括省份+车牌,不包括特殊字符,示例值:粤B888888
|
||||
*/
|
||||
private String plateNumber;
|
||||
/**
|
||||
* 车牌颜色,必传
|
||||
*/
|
||||
private PlateColor plateColor;
|
||||
/**
|
||||
* 回调通知url,必传
|
||||
* <p>
|
||||
* 接受入场状态变更回调通知的url,注意回调url只接受https
|
||||
*/
|
||||
private String notifyUrl;
|
||||
/**
|
||||
* 入场时间,必传
|
||||
* <p>
|
||||
* 格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE
|
||||
*/
|
||||
private OffsetDateTime startTime;
|
||||
/**
|
||||
* 停车场名称,必传
|
||||
*/
|
||||
private String parkingName;
|
||||
/**
|
||||
* 免费时长,必传
|
||||
* <p>
|
||||
* 单位:秒
|
||||
*/
|
||||
private Integer freeDuration;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.enumeration.PlateColor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 查询车牌服务开通信息API参数
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class ParkingServiceQueryParams {
|
||||
/**
|
||||
* 应用ID,必传
|
||||
* <p>
|
||||
* appid是商户在微信申请公众号或移动应用成功后分配的账号ID,登录平台为mp.weixin.qq.com或open.weixin.qq.com
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 车牌号,必传
|
||||
* <p>
|
||||
* 仅包括省份+车牌,不包括特殊字符,示例值:粤B888888
|
||||
*/
|
||||
private String plateNumber;
|
||||
/**
|
||||
* 车牌颜色,必传
|
||||
*/
|
||||
private PlateColor plateColor;
|
||||
/**
|
||||
* 用户标识,必传
|
||||
* <p>
|
||||
* 用户在商户对应{@code appid}下的唯一标识
|
||||
*/
|
||||
private String openid;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.v3.model.Payer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
/**
|
||||
* 订单支付结果通知API回调结果
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class TransParkingCallback {
|
||||
/**
|
||||
* 调用接口提交的应用ID
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 调用接口提交的商户号
|
||||
*/
|
||||
private String spMchid;
|
||||
/**
|
||||
* 调用接口提交的商户服务订单号
|
||||
*/
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 微信支付系统生成的订单号。
|
||||
*/
|
||||
private String transactionId;
|
||||
/**
|
||||
* 商户自定义字段,用户交易账单中对扣费服务的描述。
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 订单成功创建时返回
|
||||
*/
|
||||
private OffsetDateTime createTime;
|
||||
/**
|
||||
* 交易状态
|
||||
*/
|
||||
private ParkingTradeState tradeState;
|
||||
/**
|
||||
* 交易状态描述
|
||||
*/
|
||||
private String tradeStateDescription;
|
||||
/**
|
||||
* 支付完成时间
|
||||
*/
|
||||
private OffsetDateTime successTime;
|
||||
/**
|
||||
* 付款银行类型,参见<a target= "_blank" href= "https://pay.weixin.qq.com/wiki/doc/apiv3/terms_definition/chapter1_1_3.shtml#part-4">开户银行对照表</a>
|
||||
*/
|
||||
private String bankType;
|
||||
/**
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用,实际情况下只有支付完成状态才会返回该字段。
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 用户是否已还款
|
||||
* <p>
|
||||
* 枚举值:
|
||||
* <ul>
|
||||
* <li>Y:用户已还款</li>
|
||||
* <li>N:用户未还款</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 注意:使用此字段前需先确认bank_type字段值为BPA以及 trade_state字段值为SUCCESS。
|
||||
*/
|
||||
private String userRepaid;
|
||||
/**
|
||||
* 交易场景值,目前支持PARKING,车场停车场景
|
||||
*/
|
||||
private String tradeScene;
|
||||
/**
|
||||
* trade_scene为PARKING时,返回停车场景信息
|
||||
*/
|
||||
private ParkingInfo parkingInfo;
|
||||
/**
|
||||
* 支付者信息
|
||||
*/
|
||||
private Payer payer;
|
||||
/**
|
||||
* 订单金额信息
|
||||
*/
|
||||
private Amount amount;
|
||||
/**
|
||||
* 优惠功能信息
|
||||
*/
|
||||
private PromotionDetail promotionDetail;
|
||||
|
||||
/**
|
||||
* 交易状态
|
||||
*/
|
||||
public enum ParkingTradeState {
|
||||
/**
|
||||
* 支付成功
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* 已接收,等待扣款
|
||||
*/
|
||||
ACCEPT,
|
||||
/**
|
||||
* 支付失败(其他原因,如银行返回失败)
|
||||
*/
|
||||
PAY_FAIL,
|
||||
/**
|
||||
* 转入退款
|
||||
*/
|
||||
REFUND
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单金额信息
|
||||
*/
|
||||
@Data
|
||||
public static class Amount {
|
||||
/**
|
||||
* 订单总金额,单位为分,只能为整数
|
||||
*/
|
||||
private Integer total;
|
||||
/**
|
||||
* 订单折扣
|
||||
*/
|
||||
private Integer discountTotal;
|
||||
/**
|
||||
* 用户实际支付金额,单位为分,只能为整数
|
||||
*/
|
||||
private Integer payerTotal;
|
||||
/**
|
||||
* 符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY
|
||||
*/
|
||||
private String currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优惠功能信息
|
||||
*/
|
||||
@Data
|
||||
public static class PromotionDetail {
|
||||
/**
|
||||
* 立减优惠id
|
||||
*/
|
||||
private String promotionId;
|
||||
/**
|
||||
* 优惠券ID
|
||||
*/
|
||||
private String couponId;
|
||||
/**
|
||||
* 优惠名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 优惠范围
|
||||
*/
|
||||
private String scope;
|
||||
/**
|
||||
* 优惠类型
|
||||
* <p>
|
||||
* 枚举值:
|
||||
* <ul>
|
||||
* <li>CASH:充值型代金券</li>
|
||||
* <li>NOCASH:免充值型代金券</li>
|
||||
* </ul>
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 优惠券面额
|
||||
*/
|
||||
private Integer amount;
|
||||
/**
|
||||
* 活动ID
|
||||
*/
|
||||
private String activityId;
|
||||
/**
|
||||
* 特指由微信支付商户平台创建的优惠,出资金额等于本项优惠总金额,单位为分。
|
||||
*/
|
||||
private Integer wechatpayContribute;
|
||||
/**
|
||||
* 特指商户自己创建的优惠,出资金额等于本项优惠总金额,单位为分。
|
||||
*/
|
||||
private Integer merchantContribute;
|
||||
/**
|
||||
* 其他出资方出资金额,单位为分。
|
||||
*/
|
||||
private Integer otherContribute;
|
||||
/**
|
||||
* 优惠币种,境内商户号仅支持人民币。
|
||||
*/
|
||||
private String currency;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2019-2021 felord.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* Website:
|
||||
* https://felord.cn
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.felord.payment.wechat.v3.model.payscore.parking;
|
||||
|
||||
import cn.felord.payment.wechat.v3.model.Amount;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 扣费受理API参数
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.13.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class TransParkingParams {
|
||||
/**
|
||||
* 应用ID,必传
|
||||
* <p>
|
||||
* appid是商户在微信申请公众号或移动应用成功后分配的账号ID,登录平台为mp.weixin.qq.com或open.weixin.qq.com
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 服务描述,必传
|
||||
* <p>
|
||||
* 商户自定义字段,用于交易账单中对扣费服务的描述。
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 附加数据,非必传
|
||||
* <p>
|
||||
* 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用,实际情况下只有支付完成状态才会返回该字段。
|
||||
*/
|
||||
private String attach;
|
||||
/**
|
||||
* 商户订单号,必传
|
||||
* <p>
|
||||
* 商户系统内部订单号,只能是数字、大小写字母,且在同一个商户号下唯一
|
||||
*/
|
||||
private String outTradeNo;
|
||||
/**
|
||||
* 交易场景,必传
|
||||
* <p>
|
||||
* 目前支持 {@code PARKING} 车场停车场景
|
||||
*/
|
||||
private String tradeScene;
|
||||
/**
|
||||
* 订单优惠标记,非必传
|
||||
* <p>
|
||||
* 代金券或立减优惠功能的参数,说明详见 <a href="https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_7&index=3">代金券或立减优惠</a>
|
||||
*/
|
||||
private String goodsTag;
|
||||
/**
|
||||
* 回调通知url,必传
|
||||
*/
|
||||
private String notifyUrl;
|
||||
/**
|
||||
* 分账标识,非必传,不传则不分账
|
||||
* <p>
|
||||
* 枚举值:
|
||||
* <ul>
|
||||
* <li>Y:是,需要分账</li>
|
||||
* <li>N:否,不分账</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 字母要求大写,不传默认不分账,分账详细说明见<a href="http://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=26_1">直连分账API</a>、<a href="http://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=24_1&index=1">服务商分账API</a>文档
|
||||
*/
|
||||
private String profitSharing;
|
||||
/**
|
||||
* 订单金额,必传
|
||||
*/
|
||||
private Amount amount;
|
||||
/**
|
||||
* 停车场景信息,非必传
|
||||
* <p>
|
||||
* 当交易场景为{@code PARKING}时,需要在该字段添加停车场景信息
|
||||
*/
|
||||
private ParkingInfo parkingInfo;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user