Django Rest Framework和Stripe,最佳实践?

时间:2015-02-26 07:42:17

标签: python django rest django-rest-framework stripe-payments

我正在使用付款处理程序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 

哪一种更好的做法?或者,我是否完全忽略了这一点,应该采用不同的方式吗?

其次,有没有办法在create路由的Browsable API模板中嵌入Stripe.js和所需的表单,这样我就可以在不需要任何前端的情况下测试我的REST了?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

在我看来,正确的方法是两种提供的方法的混合,因为您应该在Stripe类中发送ModelViewSet请求,但仅在服务后保存Product实体&# 39;成功的回应。

否则,如果服务的响应不成功,我会回滚每个数据库操作(使用Django 1.6+,你可以使用transaction.atomic()记录的here来完成。

我不喜欢你的第二种方法,因为根据DRF关于create serializers.Serializer方法的文档,这个方法应该只返回给定验证数据的新实体实例,所以我会不添加其他业务逻辑。

关于第二个问题,我将构造create方法以使用注入的模拟对象来处理Stripe请求,这样您就可以测试关于任何前端交互的代码(显然这样你不进行集成测试,而是进行单元测试。