如何实现WooCommerce webhooks与Django Rest Framework的集成
WooCommerce + Django DRF Webhook 集成实现方案
问题1:适配WooCommerce Webhook请求数据格式
WooCommerce触发的Webhook请求默认携带JSON格式payload,你可以通过自定义序列化器和视图逻辑直接适配,不需要额外转换请求格式:
- 首先在Django侧定义对应数据模型,新增
wc_user_id、wc_order_id等字段作为WooCommerce侧数据的唯一关联标识,避免同步冲突 - 编写自定义序列化器映射字段,对于WooCommerce返回的嵌套结构,可以通过
source参数直接指定取值路径,示例如下:
from rest_framework import serializers from .models import WCUser, WCOrder class WCUserSyncSerializer(serializers.ModelSerializer): # 将WooCommerce返回的用户id映射到Django模型的wc_user_id字段 wc_user_id = serializers.IntegerField(source='id') # 取嵌套的账单邮箱字段 billing_email = serializers.CharField(source='billing.email', required=False) class Meta: model = WCUser fields = ['wc_user_id', 'first_name', 'last_name', 'email', 'billing_email', 'status']
- 编写统一的Webhook处理视图,通过WooCommerce自带的
X-WC-Webhook-Topic请求头区分事件类型,分别处理用户、订单、订阅的同步逻辑,示例如下:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .serializers import WCUserSyncSerializer, WCOrderSyncSerializer from .models import WCUser class WooWebhookView(APIView): def post(self, request): # 获取当前Webhook的事件类型 topic = request.META.get('HTTP_X_WC_WEBHOOK_TOPIC') payload = request.data # 处理用户创建事件 if topic == 'customer.created': serializer = WCUserSyncSerializer(data=payload) if serializer.is_valid(): serializer.save() return Response(status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 处理用户更新事件 elif topic == 'customer.updated': wc_user = WCUser.objects.get(wc_user_id=payload['id']) serializer = WCUserSyncSerializer(wc_user, data=payload, partial=True) if serializer.is_valid(): serializer.save() return Response(status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 处理用户删除事件 elif topic == 'customer.deleted': WCUser.objects.filter(wc_user_id=payload['id']).delete() return Response(status=status.HTTP_204_NO_CONTENT) # 订单、订阅类事件同理添加对应分支即可,订阅事件topic为WooCommerce Subscriptions插件提供:subscription.created、subscription.renewed、subscription.expired else: return Response(status=status.HTTP_404_NOT_FOUND)
问题2:Token认证失败问题
报错原因是WooCommerce发送的请求没有携带DRF要求格式的认证凭证,按以下步骤排查修正:
- 首先确认Django侧DRF Token认证配置正确,
settings.py配置示例:
INSTALLED_APPS = [ # 其他原有应用 'rest_framework', 'rest_framework.authtoken', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] }
配置完成后执行python manage.py migrate生成token存储表,确认你生成的token是rest_framework.authtoken.models.Token表中存储的有效字符串。
- 进入WooCommerce Webhook配置页,找到「高级设置-请求头」配置项,新增自定义请求头:
- 头名称填
Authorization - 头值填
Token 你的DRF令牌字符串,注意Token和令牌之间必须有1个空格,不要写成Bearer前缀,DRF默认认证前缀为Token
- 头名称填
- 若仍认证失败,可在视图中临时添加日志打印所有请求头,确认WooCommerce是否正常发送了
Authorization头:
def post(self, request): # 临时打印请求头排查问题 print(request.META) # 原有业务逻辑
额外优化建议
- 新增签名校验逻辑:通过WooCommerce请求头
X-WC-Webhook-Signature做HMAC SHA256校验,使用Webhook配置时设置的密钥作为加密盐,避免伪造请求 - 配置Webhook重试规则:WooCommerce默认对返回非200状态码的请求自动重试,可根据业务需要调整重试次数,避免数据漏同步
内容的提问来源于stack exchange,提问作者calin.bule
相关产品推荐
相关产品推荐

