#Invalid data. Expected a dictionary, but got int. Even with the same schema.

10 messages · Page 1 of 1 (latest)

brittle hazel
#

These are my models:

class Customer(models.Model):
    name = models.CharField(max_length=200, default="abcd")
    email = models.EmailField(max_length=200, unique=True, default="abcd@efg.com")
    phone_number = models.CharField(max_length=20)
    address = models.CharField(max_length=500)

This is the serializer:

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = "__all__"
#

This is the view:

class PhonePePaymentView(APIView):
    def post(self, request):
        # Get the payment details from the request
        payment_details = request.data

        # Check if customer exists
        customer_data = request.data.get("customer")
        print(customer_data["phone_number"])
        try:
            customer = Customer.objects.get(phone_number=customer_data["phone_number"])
        except Customer.DoesNotExist:
            serializer = CustomerSerializer(data=customer_data)
            if serializer.is_valid():
                customer = serializer.save()
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
                # If the serialized data is not valid, return the errors
        # Setup PhonePe client
        merchant_id = settings.PHONEPE_MERCHANT_ID
        salt_key = settings.PHONEPE_SALT_KEY
        salt_index = int(settings.PHONEPE_SALT_INDEX)

        print(merchant_id, salt_key, salt_index)
        env = Env.PROD  

        phonepe_client = PhonePePaymentClient(
            merchant_id=merchant_id, salt_key=salt_key, salt_index=salt_index, env=env
        )


        product_ids = payment_details.get("product_ids", [])
        total_amount = sum(
            Product.objects.filter(id__in=product_ids).values_list("price", flat=True)
        )
        if payment_details.get("coupon_code"):
            coupon = Coupon.objects.get(code=payment_details.get("coupon_code"))
            total_amount -= coupon.amount

        # Create a new pay page request
        pay_page_request = PgPayRequest.pay_page_pay_request_builder(
            merchant_transaction_id=str(uuid.uuid4()),
            amount=total_amount,
            merchant_user_id=customer.id,
            callback_url=settings.PHONEPE_S2S_CALLBACK_URL,
            redirect_url=settings.PHONEPE_UI_REDIRECT_URL,
        )
#
       # Create a new order
        order_data = {
            "order_status": "Placed",
            "payment_method": "Online",
            "customer": customer.id,
            "items": payment_details.get("items", []),
            "order_value": total_amount,
            "payment_id": None,
        }
        order_serializer = OrderSerializer(data=order_data)
        if order_serializer.is_valid():
            order = order_serializer.save()
        else:
            return Response(order_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        # Create a new payment
        payment = phonepe_client.pay(pay_page_request)

        # Update the order with the payment ID
        order.payment_id = payment.data.instrument_response.payment_id
        order.save()

        # Return the payment details
        # The payment details include the payment URL, which can be used to redirect the customer to the PhonePe payment page.
        return Response(
            {
                "payment_id": payment.data.instrument_response.payment_id,
                "payment_url": payment.data.instrument_response.redirect_info.url,
            },
            status=201,
        )
#

This is the request:

{
  "product_ids": [1],
  "items": [
    {
      "product_id": 1,
      "quantity": 1
    }
  ],
  "customer": {
    "name": "John Doe",
    "email": "john.doe@example.com",
    "phone_number": "+919876543210",
    "address": "123 Main St, Anytown, USA"
  }
}
#

This is the response:

{
  "customer": {
    "non_field_errors": [
      "Invalid data. Expected a dictionary, but got int."
    ]
  }
}
#

I printed customer data just to check if any oversight:

{
    "name": "John Doe",
    "email": "john.doe@example.com",
    "phone_number": "+919876543210",
    "address": "123 Main St, Anytown, USA"
  }

But its the same.

#

Please help it's urgent!

#

Invalid data. Expected a dictionary, but got int. Even with the same schema.

plush steeple
#

You call is_valid twice. Once for the customer serializer and the second for the order serializer. The first seems fine as you have researched.

The order seems suspect since you're assigning an integer to the customer field and the error says it's getting an int instead of a dict.

You need to handle how order deals with the customer on create. My suggestion would be to make customer read only, then add a field called customer_id that's write only. Then specify customer_id when crafting this serializer instance in your view.

brittle hazel