1
0
mirror of synced 2026-10-10 17:02:13 +08:00

🆕 #4103 【视频号】补齐售后服务代发起售后、退差价、虚拟号、极速换货、保障单和工单同步等接口方法

This commit is contained in:
Binary Wang
2026-08-22 20:29:24 +08:00
committed by GitHub
parent 4e2fbf725e
commit f994a17074
13 changed files with 316 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
@Data
@EqualsAndHashCode(callSuper = true)
public class AfterSaleCreateResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 2680676438284658410L;
@JsonProperty("after_sale_order_id")
private String afterSaleOrderId;
}

View File

@@ -0,0 +1,25 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AfterSaleGenAfterSaleOrderParam extends AfterSaleRefundPriceDiffParam {
private static final long serialVersionUID = -6873909673739068936L;
@JsonProperty("count")
private Integer count;
@JsonProperty("type")
private String type;
@JsonProperty("address_id")
private String addressId;
@JsonProperty("exchange_sku_info")
private ExchangeSkuInfo exchangeSkuInfo;
}

View File

@@ -0,0 +1,29 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AfterSaleHandleFastExchangeReceiptParam extends AfterSaleIdParam {
private static final long serialVersionUID = 5430106715116197677L;
@JsonProperty("act")
private Integer act;
@JsonProperty("reject_reason")
private String rejectReason;
@JsonProperty("reject_reason_type")
private Integer rejectReasonType;
@JsonProperty("merchant_text")
private String merchantText;
@JsonProperty("reject_confirm_exchange")
private List<String> rejectConfirmExchange;
}

View File

@@ -0,0 +1,33 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AfterSaleRefundPriceDiffParam implements Serializable {
private static final long serialVersionUID = 3875058376021518123L;
@JsonProperty("request_id")
private String requestId;
@JsonProperty("order_id")
private String orderId;
@JsonProperty("product_id")
private String productId;
@JsonProperty("sku_id")
private String skuId;
@JsonProperty("amount")
private Integer amount;
@JsonProperty("reason")
private String reason;
@JsonProperty("desc")
private String desc;
}

View File

@@ -0,0 +1,18 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
@Data
@EqualsAndHashCode(callSuper = true)
public class AfterSaleVirtualTelNumResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = -2715343569103426942L;
@JsonProperty("virtual_tel_number")
private String virtualTelNumber;
@JsonProperty("virtual_tel_expire_time")
private Long virtualTelExpireTime;
}

View File

@@ -0,0 +1,14 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ExchangeSkuInfo implements Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("new_sku_id")
private String newSkuId;
}

View File

@@ -0,0 +1,19 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GuaranteeMerchantModifyParam extends GuaranteeOrderIdParam {
private static final long serialVersionUID = 9193536167701367687L;
@JsonProperty("bad_level")
private Integer badLevel;
@JsonProperty("merchant_remark")
private String merchantRemark;
}

View File

@@ -0,0 +1,19 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GuaranteeMerchantProofParam extends GuaranteeOrderIdParam {
private static final long serialVersionUID = -2365495841866160967L;
@JsonProperty("content")
private String content;
@JsonProperty("pic_list")
private java.util.List<String> picList;
}

View File

@@ -0,0 +1,16 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
@Data
@EqualsAndHashCode(callSuper = true)
public class GuaranteeOrderResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 3977781489692530604L;
@JsonProperty("guarantee_order")
private JsonNode guaranteeOrder;
}

View File

@@ -0,0 +1,79 @@
package me.chanjar.weixin.channel.bean.after;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SyncWorkOrderParam implements Serializable {
private static final long serialVersionUID = -7336088606071452113L;
@JsonProperty("complaint_id")
private String complaintId;
@JsonProperty("work_order_info")
private WorkOrderInfo workOrderInfo;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class WorkOrderInfo implements Serializable {
private static final long serialVersionUID = 8573016851280130766L;
@JsonProperty("version")
private Integer version;
@JsonProperty("items")
private List<WorkOrderItem> items;
@JsonProperty("work_order_id")
private String workOrderId;
}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class WorkOrderItem implements Serializable {
private static final long serialVersionUID = 6925580701152256736L;
@JsonProperty("status")
private Integer status;
@JsonProperty("desc")
private String desc;
@JsonProperty("update_time")
private Long updateTime;
@JsonProperty("result_type")
private Integer resultType;
@JsonProperty("refund_amount")
private Integer refundAmount;
@JsonProperty("media_list")
private List<WorkOrderMedia> mediaList;
}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class WorkOrderMedia implements Serializable {
private static final long serialVersionUID = 2258990333977395631L;
@JsonProperty("type")
private Integer type;
@JsonProperty("picture")
private WorkOrderPicture picture;
}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class WorkOrderPicture implements Serializable {
private static final long serialVersionUID = -3339842364541603289L;
@JsonProperty("tmp_media_id")
private String tmpMediaId;
}
}

View File

@@ -298,6 +298,15 @@ public class WxChannelApiUrlConstants {
/** 售后相关接口 */
public interface AfterSale {
String AFTER_SALE_GEN_AFTER_SALE_ORDER_URL = "https://api.weixin.qq.com/channels/ec/aftersale/genaftersaleorder";
String AFTER_SALE_REFUND_PRICE_DIFF_URL = "https://api.weixin.qq.com/channels/ec/aftersale/refundpricediff";
String AFTER_SALE_APPLY_VIRTUAL_TEL_NUM_URL = "https://api.weixin.qq.com/channels/ec/aftersale/applyvirtualtelnum";
String AFTER_SALE_HANDLE_FAST_EXCHANGE_RECEIPT_URL = "https://api.weixin.qq.com/channels/ec/aftersale/handlefastexchangereceipt";
String AFTER_SALE_GET_GUARANTEE_ORDER_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getguaranteeorder";
String AFTER_SALE_MERCHANT_ACCEPT_GUARANTEE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantacceptguarantee";
String AFTER_SALE_MERCHANT_MODIFY_GUARANTEE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantmodifyguarantee";
String AFTER_SALE_MERCHANT_PROOF_GUARANTEE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantproofguarantee";
String AFTER_SALE_SYNC_WORK_ORDER_URL = "https://api.weixin.qq.com/channels/ec/aftersale/syncworkorder";
/** 获取售后列表 */
String AFTER_SALE_LIST_URL = "https://api.weixin.qq.com/channels/ec/aftersale/getaftersalelist";

View File

@@ -0,0 +1,39 @@
package me.chanjar.weixin.channel.bean.after;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Collections;
import org.testng.annotations.Test;
public class AfterSaleContractTest {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Test
public void shouldUseOfficialAfterSaleAndGuaranteeFieldNames() throws Exception {
AfterSaleGenAfterSaleOrderParam afterSaleParam = new AfterSaleGenAfterSaleOrderParam();
ExchangeSkuInfo exchangeSkuInfo = new ExchangeSkuInfo();
exchangeSkuInfo.setNewSkuId("new-sku");
afterSaleParam.setExchangeSkuInfo(exchangeSkuInfo);
AfterSaleHandleFastExchangeReceiptParam receiptParam = new AfterSaleHandleFastExchangeReceiptParam();
receiptParam.setRejectConfirmExchange(Collections.singletonList("media-1"));
GuaranteeOrderIdParam guaranteeParam = new GuaranteeOrderIdParam("guarantee-1");
assertTrue(OBJECT_MAPPER.writeValueAsString(afterSaleParam).contains("\"exchange_sku_info\":{\"new_sku_id\":\"new-sku\"}"));
assertTrue(OBJECT_MAPPER.writeValueAsString(receiptParam).contains("\"reject_confirm_exchange\":[\"media-1\"]"));
assertTrue(OBJECT_MAPPER.writeValueAsString(guaranteeParam).contains("\"guarantee_order_id\":\"guarantee-1\""));
}
@Test
public void shouldDecodeOfficialResponseFields() throws Exception {
AfterSaleCreateResponse createResponse = OBJECT_MAPPER.readValue(
"{\"errcode\":0,\"after_sale_order_id\":\"after-1\"}", AfterSaleCreateResponse.class);
GuaranteeOrderResponse guaranteeResponse = OBJECT_MAPPER.readValue(
"{\"errcode\":0,\"guarantee_order\":{\"guarantee_order_id\":\"guarantee-1\"}}", GuaranteeOrderResponse.class);
assertEquals(createResponse.getAfterSaleOrderId(), "after-1");
assertEquals(guaranteeResponse.getGuaranteeOrder().get("guarantee_order_id").asText(), "guarantee-1");
}
}

View File

@@ -14,6 +14,7 @@
<class name="me.chanjar.weixin.channel.util.XmlUtilsTest"/>
<class name="me.chanjar.weixin.channel.util.WxChCryptUtilsTest"/>
<class name="me.chanjar.weixin.channel.util.ResponseUtilsTest"/>
<class name="me.chanjar.weixin.channel.bean.after.AfterSaleContractTest"/>
</classes>
</test>
<test name="Service_Test">