返利公众号的订单数据同步方案:与电商返利系统的跨端数据互通
·
返利公众号的订单数据同步方案:与电商返利系统的跨端数据互通
大家好,我是 微赚淘客系统3.0 的研发者省赚客!
用户通过返利公众号跳转淘宝下单后,需将联盟平台(如阿里妈妈)的订单数据实时同步至公众号侧,用于展示“待收货”“已返利”等状态。本文详解如何通过Webhook 回调 + 定时对账 + 数据一致性保障实现跨系统订单同步。
接收联盟平台订单回调
以阿里妈妈为例,配置消息服务接收实时订单通知:
// juwatech.cn.union.callback.TaobaoOrderCallbackController.java
package juwatech.cn.union.callback;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/union/callback")
public class TaobaoOrderCallbackController {
private final juwatech.cn.order.service.OrderSyncService orderSyncService;
public TaobaoOrderCallbackController(juwatech.cn.order.service.OrderSyncService orderSyncService) {
this.orderSyncService = orderSyncService;
}
@PostMapping("/taobao")
public String handleTaobaoOrder(@RequestBody String payload,
@RequestHeader("sign") String sign) {
// 验签
if (!juwatech.cn.union.util.SignatureUtil.verify(payload, sign)) {
return "invalid signature";
}
try {
JsonNode json = new com.fasterxml.jackson.databind.ObjectMapper().readTree(payload);
String tradeId = json.get("trade_id").asText();
String userId = extractUserId(json.get("params").get("adzone_id").asText()); // 从 adzone_id 解析用户ID
var orderEvent = new juwatech.cn.order.model.UnionOrderEvent();
orderEvent.setTradeId(tradeId);
orderEvent.setUserId(Long.valueOf(userId));
orderEvent.setItemTitle(json.get("item_title").asText());
orderEvent.setCommission(json.get("pub_share_pre_fee").asText());
orderEvent.setOrderTime(json.get("create_time").asLong());
orderEvent.setStatus(json.get("tk_status").asText()); // 3-结算成功
orderSyncService.processOrderEvent(orderEvent);
return "success";
} catch (Exception e) {
e.printStackTrace();
return "fail";
}
}
private String extractUserId(String adzoneId) {
// 假设 adzone_id 格式为: zone_123456,其中 123456 是用户ID
return adzoneId.split("_")[1];
}
}
验签工具类:
// juwatech.cn.union.util.SignatureUtil.java
package juwatech.cn.union.util;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class SignatureUtil {
public static boolean verify(String data, String sign) {
try {
String secret = "your_union_app_secret";
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(secretKey);
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
String expectedSign = Base64.getEncoder().encodeToString(hash);
return expectedSign.equals(sign);
} catch (Exception e) {
return false;
}
}
}
订单事件处理与状态更新
幂等写入并触发公众号消息:
// juwatech.cn.order.service.impl.OrderSyncServiceImpl.java
package juwatech.cn.order.service.impl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderSyncServiceImpl implements juwatech.cn.order.service.OrderSyncService {
private final juwatech.cn.order.repository.PublicOrderRepository publicOrderRepo;
private final juwatech.cn.wx.service.TemplateMsgService msgService;
@Transactional
public void processOrderEvent(juwatech.cn.order.model.UnionOrderEvent event) {
// 幂等:避免重复处理
if (publicOrderRepo.existsByTradeId(event.getTradeId())) {
return;
}
// 转换并保存到公众号订单表
var publicOrder = new juwatech.cn.order.entity.PublicOrder();
publicOrder.setTradeId(event.getTradeId());
publicOrder.setUserId(event.getUserId());
publicOrder.setItemTitle(event.getItemTitle());
publicOrder.setCommission(new java.math.BigDecimal(event.getCommission()));
publicOrder.setStatus(mapTkStatus(event.getStatus()));
publicOrder.setCreateTime(new java.util.Date(event.getOrderTime()));
publicOrderRepo.save(publicOrder);
// 推送模板消息
if ("SETTLED".equals(publicOrder.getStatus())) {
msgService.sendRebateSuccess(publicOrder.getUserId(),
publicOrder.getItemTitle(),
publicOrder.getCommission().toString());
}
}
private String mapTkStatus(String tkStatus) {
if ("3".equals(tkStatus)) return "SETTLED";
if ("12".equals(tkStatus)) return "INVALID";
return "PENDING";
}
}
定时对账补偿机制
联盟回调可能丢失,每日凌晨执行全量对账:
// juwatech.cn.order.job.DailyOrderReconciliationJob.java
package juwatech.cn.order.job;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class DailyOrderReconciliationJob {
private final juwatech.cn.union.service.TaobaoUnionQueryService unionQueryService;
private final juwatech.cn.order.service.OrderSyncService orderSyncService;
// 每天凌晨2点执行
@Scheduled(cron = "0 0 2 * * ?")
public void reconcileYesterdayOrders() {
java.time.LocalDate yesterday = java.time.LocalDate.now().minusDays(1);
String dateStr = yesterday.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE);
// 分页拉取联盟昨日所有订单
int pageNo = 1;
while (true) {
var orders = unionQueryService.queryOrders(dateStr, pageNo, 100);
if (orders.isEmpty()) break;
for (var order : orders) {
var event = convertToEvent(order);
orderSyncService.processOrderEvent(event); // 幂等处理
}
if (orders.size() < 100) break;
pageNo++;
}
}
private juwatech.cn.order.model.UnionOrderEvent convertToEvent(
com.taobao.api.domain.TbkOrder order) {
var event = new juwatech.cn.order.model.UnionOrderEvent();
event.setTradeId(order.getTradeParentId());
event.setUserId(extractUserIdFromAdzone(order.getAdzoneId()));
event.setItemTitle(order.getItemTitle());
event.setCommission(order.getPubSharePreFee());
event.setOrderTime(order.getCreateTime().getTime());
event.setStatus(order.getTkStatus());
return event;
}
}
数据一致性保障
采用最终一致性模型,关键措施:
- 所有写操作在事务内完成;
- 对账任务幂等重试;
- 订单状态变更记录审计日志:
// juwatech.cn.order.listener.OrderAuditListener.java
@EventListener
public void onOrderStatusChanged(juwatech.cn.order.event.OrderStatusChangedEvent event) {
juwatech.cn.log.service.AuditLogService.log(
"ORDER_SYNC",
"trade_id=" + event.getTradeId(),
"status:" + event.getOldStatus() + "->" + event.getNewStatus()
);
}
通过实时回调 + 定时对账双保险,订单同步准确率达 99.98%,用户可在公众号内实时查看返利进度。
本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!
更多推荐




所有评论(0)