mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-14 05:43:46 +08:00
wechat pay score api
This commit is contained in:
@@ -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"),
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
} catch (CertificateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Certificate certificate = certificateFactory.generateCertificate(inputStream);
|
||||
String responseSerialNo = objectNode.get("serial_no").asText();
|
||||
CERTIFICATE_MAP.put(responseSerialNo, certificate);
|
||||
} catch (CertificateException e) {
|
||||
throw new PayException("An error occurred while generating the wechat v3 certificate, reason : " + e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解密响应体.
|
||||
*
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.function.Consumer;
|
||||
* 微信支付回调工具.
|
||||
* <p>
|
||||
* 支付通知http应答码为200或204才会当作正常接收,当回调处理异常时,应答的HTTP状态码应为500,或者4xx。
|
||||
*
|
||||
* TODO 微信支付分有三个回调通知
|
||||
* @author felord.cn
|
||||
* @since 1.0.0.RELEASE
|
||||
*/
|
||||
|
||||
@@ -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<ObjectNode> createServiceOrder(UserPayScoreOrderParams params) {
|
||||
public WechatResponseEntity<ObjectNode> createServiceOrder(UserServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> 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<ObjectNode> 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
|
||||
* <p>
|
||||
* 完结订单总金额与实际金额不符时,可通过该接口修改订单金额。
|
||||
* 例如:充电宝场景,由于机器计费问题导致商户完结订单时扣除用户99元,用户客诉成功后,商户需要按照实际的消费金额(如10元)扣费,当服务订单支付状态处于“待支付”时,商户可使用此能力修改订单金额。
|
||||
* <p>
|
||||
* 注意:
|
||||
* • 若此笔订单已收款成功,商户直接使用退款能力,将差价退回用户即可。
|
||||
* <p>
|
||||
* • 修改次数>=1,第n次修改后金额 <第n-1次修改后金额
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> modifyServiceOrder(ModifyServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> 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
|
||||
* <p>
|
||||
* 前置条件:服务订单状态为“进行中”且订单状态说明需为[USER_CONFIRM:用户确认]
|
||||
* <p>
|
||||
* 完结微信支付分订单。用户使用服务完成后,商户可通过此接口完结订单。
|
||||
* <p>
|
||||
* 特别说明:
|
||||
* • 完结接口调用成功后,微信支付将自动发起免密代扣。 若扣款失败,微信支付将自动再次发起免密代扣(按照一定频次),直到扣成功为止。
|
||||
*
|
||||
* @param params the params
|
||||
* @return wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> completeServiceOrder(CompleteServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> 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
|
||||
* <p>
|
||||
* 前置条件:服务订单支付状态处于“待支付”状态
|
||||
* <p>
|
||||
* 当微信支付分订单支付状态处于“待支付”时,商户可使用该接口向用户发起收款。
|
||||
* <p>
|
||||
* 注意:
|
||||
* • 此能力不影响微信支付分代商户向用户发起收款的策略。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> payServiceOrder(PayServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> 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
|
||||
* <p>
|
||||
* 前提条件:同步商户渠道收款成功信息时,即场景类型=“Order_Paid”,订单的状态需为[MCH_COMPLETE:商户完结订单]
|
||||
* <p>
|
||||
* 由于收款商户进行的某些“线下操作”会导致微信支付侧的订单状态与实际情况不符。例如,用户通过线下付款的方式已经完成支付,而微信支付侧并未支付成功,此时可能导致用户重复支付。因此商户需要通过订单同步接口将订单状态同步给微信支付,修改订单在微信支付系统中的状态。
|
||||
*
|
||||
* @param params the params
|
||||
* @return the wechat response entity
|
||||
*/
|
||||
public WechatResponseEntity<ObjectNode> syncServiceOrder(SyncServiceOrderParams params) {
|
||||
WechatResponseEntity<ObjectNode> 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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 商户服务订单号,必填
|
||||
* <p>
|
||||
* 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。
|
||||
*/
|
||||
private String outOrderNo;
|
||||
/**
|
||||
* 与传入的商户号建立了支付绑定关系的appid,必填
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 服务ID,必填
|
||||
* <p>
|
||||
* 该服务ID有本接口对应产品的权限。
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 后付费项目,必填
|
||||
*/
|
||||
private List<PostPayment> postPayments;
|
||||
/**
|
||||
* 后付费商户优惠,选填
|
||||
*/
|
||||
private List<PostDiscount> postDiscounts;
|
||||
/**
|
||||
* 总金额,单位分,必填
|
||||
* <p>
|
||||
* 不能超过完结订单时候的总金额,只能为整数,详见 <a target= "_blank" href= "https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=4_2">支付金额</a>。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n)
|
||||
*/
|
||||
private Long totalAmount;
|
||||
/**
|
||||
* 服务时间段,条件选填
|
||||
* <p>
|
||||
* 服务时间范围,创建订单未填写服务结束时间,则完结的时候,服务结束时间必填
|
||||
* 如果传入,用户侧则显示此参数。
|
||||
*/
|
||||
private TimeRange timeRange;
|
||||
/**
|
||||
* 服务位置,选填
|
||||
*/
|
||||
private CompleteLocation location;
|
||||
/**
|
||||
* 微信支付服务分账标记,选填
|
||||
* <p>
|
||||
* 完结订单分账接口标记。分账开通流程,详见 <a target = "_blank" href = "https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=26_2">分账</a>
|
||||
* false:不分账,默认:false
|
||||
* true:分账。
|
||||
*/
|
||||
private Boolean profitSharing = Boolean.TRUE;
|
||||
/**
|
||||
* 订单优惠标记,选填
|
||||
* <p>
|
||||
* 代金券或立减金优惠的参数,说明详见代金券或立减金优惠
|
||||
*/
|
||||
private String goods_tag;
|
||||
|
||||
|
||||
/**
|
||||
* 服务位置信息
|
||||
* <p>
|
||||
* 如果传入,用户侧则显示此参数。
|
||||
*
|
||||
* @author felord.cn
|
||||
* @since 1.0.2.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public static class CompleteLocation {
|
||||
|
||||
/**
|
||||
* 预计服务结束地点,条件选填。
|
||||
* <p>
|
||||
* 结束使用服务的地点,不超过50个字符,超出报错处理 。 创建订单传入了【服务开始地点】,此项才能填写
|
||||
* 【建议】
|
||||
* 1、预计结束地点为空时,实际结束地点与开始地点相同,不填写
|
||||
* 2、预计结束地点不为空时,实际结束地点与预计结束地点相同,不填写
|
||||
*/
|
||||
private String endLocation;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 商户服务订单号,必填
|
||||
* <p>
|
||||
* 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。
|
||||
*/
|
||||
private String outOrderNo;
|
||||
/**
|
||||
* 与传入的商户号建立了支付绑定关系的appid,必填
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 服务ID,必填
|
||||
* <p>
|
||||
* 该服务ID有本接口对应产品的权限。需要与创建订单时保持一致。
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 后付费项目,必填
|
||||
*/
|
||||
private List<PostPayment> postPayments;
|
||||
/**
|
||||
* 后付费商户优惠,选填
|
||||
*/
|
||||
private List<PostDiscount> postDiscounts;
|
||||
/**
|
||||
* 总金额,单位分,必填
|
||||
*
|
||||
* 不能超过完结订单时候的总金额,只能为整数,详见 <a target= "_blank" href= "https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=4_2">支付金额</a>。此参数需满足:总金额 =(修改后付费项目1…+修改后完结付费项目n)-(修改 后付费商户优惠项目1…+修改后付费商户优惠项目n)
|
||||
*/
|
||||
private Long totalAmount;
|
||||
/**
|
||||
* 取消原因,最长50个字符,必填
|
||||
*/
|
||||
private String reason;
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 商户服务订单号,必填
|
||||
* <p>
|
||||
* 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。
|
||||
*/
|
||||
private String outOrderNo;
|
||||
/**
|
||||
* 与传入的商户号建立了支付绑定关系的appid,必填
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 服务ID,必填
|
||||
* <p>
|
||||
* 该服务ID有本接口对应产品的权限。
|
||||
*/
|
||||
private String serviceId;
|
||||
}
|
||||
@@ -26,6 +26,11 @@ public class PostDiscount {
|
||||
* 优惠使用条件说明。{@link PostDiscount#name}若填写,则必须同时填写。
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 总金额,单位分,必填
|
||||
* todo 新增没有此字段,修改必填,感觉不太符合常理
|
||||
*/
|
||||
private Long amount;
|
||||
/**
|
||||
* 优惠数量,选填。
|
||||
* <p>
|
||||
|
||||
@@ -14,13 +14,13 @@ import lombok.Data;
|
||||
@Data
|
||||
public class PostPayment {
|
||||
/**
|
||||
* 付费项目名称,选填。
|
||||
* 付费项目名称,选填。 修改订单必填
|
||||
* <p>
|
||||
* 相同订单号下不能出现相同的付费项目名称,当参数长度超过20个字符时,报错处理。
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 金额,条件选填。
|
||||
* 金额,条件选填。修改订单必填
|
||||
* <p>
|
||||
* 此付费项目总金额,大于等于0,单位为分,等于0时代表不需要扣费,只能为整数,详见支付金额。如果填写了“付费项目名称”,则amount或description必须填写其一,或都填。
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ public class RiskFund {
|
||||
* 1、数字,必须>0(单位分)。
|
||||
* 2、风险金额≤每个服务ID的风险金额上限。
|
||||
* 3、当商户优惠字段为空时,付费项目总金额≤服务ID的风险金额上限 (未填写金额的付费项目,视为该付费项目金额为0)。
|
||||
* 4、完结金额可大于、小于或等于风险金额。详细可见QA <a src = "https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/payscore/chapter11_2.shtml#menu1">关于订单风险金额问题</a>
|
||||
* 4、完结金额可大于、小于或等于风险金额。详细可见QA <a target= "_blank" href= "https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/payscore/chapter11_2.shtml#menu1">关于订单风险金额问题</a>
|
||||
*/
|
||||
private Long amount;
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
* 商户服务订单号,必填
|
||||
* <p>
|
||||
* 商户系统内部服务订单号(不是交易单号),要求此参数只能由数字、大小写字母_-|*组成,且在同一个商户号下唯一。详见[商户订单号]。
|
||||
*/
|
||||
private String outOrderNo;
|
||||
/**
|
||||
* 与传入的商户号建立了支付绑定关系的appid,必填
|
||||
*/
|
||||
private String appid;
|
||||
/**
|
||||
* 服务ID,必填
|
||||
* <p>
|
||||
* 该服务ID有本接口对应产品的权限。与订单要保持一致。
|
||||
*/
|
||||
private String serviceId;
|
||||
/**
|
||||
* 场景类型,必填,场景类型为“Order_Paid”,字符串表示“订单收款成功” 。
|
||||
*/
|
||||
private String type = "Order_Paid";
|
||||
|
||||
/**
|
||||
* 内容信息详情,场景类型为Order_Paid时,为必填项。
|
||||
*/
|
||||
private SyncDetail detail;
|
||||
|
||||
|
||||
/**
|
||||
* 内容信息详情
|
||||
*/
|
||||
@Data
|
||||
public static class SyncDetail{
|
||||
/**
|
||||
* 收款成功时间
|
||||
* <p>
|
||||
* 支付成功时间,支持两种格式: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;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
* @since 1.0.2.RELEASE
|
||||
*/
|
||||
@Data
|
||||
public class UserPayScoreOrderParams {
|
||||
public class UserServiceOrderParams {
|
||||
|
||||
/**
|
||||
* 商户服务订单号,必填
|
||||
Reference in New Issue
Block a user