Django Rest Framework和Stripe,最佳实践是什么?

6

我在使用支付处理程序Stripe时,为DRF结构中的哲学问题而苦恼。 我通过DRF REST API销售具有Django模型Product的产品。 我在思考是否应该创建Product,然后像下面这样在我的create视图中处理付款:

class ProductViewSet(viewsets.ModelViewSet):

...

def create(self, request):
    serializer = ProductSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    product = serializer.save()

    try:
        response = stripe.Charge.create(
            amount=product.cost,
            currency="usd",
            source=request.data["token"], # Done with Stripe.js
            description="Product"
        )
        product.charge_id = response.charge_id

        ...

或者,反之,如果我应该在Product序列化器中处理付款:

class ProductSerializer(serializers.Serializer):

    ...

    def create(self, validated_data):
        product = Product.objects.create(**validated_data)

        # Will raise an Excetpion and stop the creation:
        response = stripe.Charge.create(
            amount=product.cost,
            currency="usd",
            source=validated_data["token"], # Done with Stripe.js
            description="Product"
        )


        return product 

哪种做法更好?或者,我完全错了,应该采用不同的方法吗?

其次,是否有一种方法可以在Browsable API模板中嵌入Stripe.js和所需的表单,以便我可以在不需要任何前端的情况下测试我的REST?

谢谢你的帮助。

1个回答

1
在我看来,正确的方法是将Stripe请求发送到ModelViewSet类中,但仅在服务成功响应后保存Product实体。否则,如果服务的响应不成功,我会回滚每个数据库操作(使用Django 1.6+可以使用transaction.atomic()来实现,文档链接here)。我不喜欢你的第二种方法,因为根据DRF关于serializers.Serializercreate方法的文档,此方法应该仅返回已验证数据的新实体实例,所以我不会添加其他业务逻辑。关于第二个问题,我会结构化create方法,使用一个注入的模拟对象来进行Stripe请求,在这种方式下,您可以针对任何前端交互测试您的代码(显然,您不进行集成测试而是进行单元测试)。

谢谢。在我的视图中,在创建对象product= serializer.save()之前,我只是在验证数据serializer.is_valid(raise_exception=True)后进行充电。有点遗憾的是,我必须从request.data中检索一些数据来收费...你能在第二部分添加更多细节(例如代码片段)吗? - user2024621

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接