I keep getting the following error when trying to post to PayPal:
shippingData = json.loads(request.body)
django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
I have tried removing the request.headers, this does nothing. I tried removing CRSF Token altogether and still the same error. I have also tried renaming request.body into a different variable, this also does not remove the error. Replacing with request.data just gives a different error also.
This is my view:
def create_order(request):
customer = Customer.objects.get(user=request.user)
shippingData = json.loads(request.body)
first_name = customer.first_name
last_name = customer.last_name
ShippingAddress.objects.create(
customer=customer,
house=shippingData['shipping']['house'],
street=shippingData['shipping']['street'],
city=shippingData['shipping']['city'],
postcode=shippingData['shipping']['postcode'],
)
# assuming you have retrieved the ShippingAddress object for the given customer
shipping_address_queryset = ShippingAddress.objects.filter(customer=customer)
if shipping_address_queryset.exists():
shipping_address = shipping_address_queryset.first()
# extract the necessary fields from the shipping_address object
house = shipping_address.house
street = shipping_address.street
city = shipping_address.city
postcode = shipping_address.postcode
user_cart = Cart.objects.filter(user=request.user).first()
if user_cart:
# get cart items and total
cart_items = user_cart.items.all()
cart_total = user_cart.get_cart_total()
# create the items list
items = []
for item in cart_items:
items.append({
"name": item.product.title,
"description": "",
"quantity": str(item.quantity),
"unit_amount": {
"currency_code": "GBP",
"value": "{:.2f}".format(item.product.price)
},
"tax": {
"currency_code": "GBP",
"value": "0.00"
}
})
# calculate the breakdown for the purchase unit
item_total = sum(float(item["unit_amount"]["value"]) * int(item["quantity"]) for item in items)
amount_breakdown = {
"item_total": {
"currency_code": "GBP",
"value": "{:.2f}".format(item_total)
},
"shipping": {
"currency_code": "GBP",
"value": "0.00"
},
}
access_token = settings.PAYPAL_ACCESS_TOKEN
# Create a new PayPal order
headers = {
'Content-Type': 'application/json',
'X-CSRFToken': request.headers['X-CSRFToken'],
'Authorization': 'Bearer ' + access_token,
}
data = {
"intent": "CAPTURE",
"paypal": {
"experience_context": {
"payment_method_preference": "IMMEDIATE_PAYMENT_REQUIRED",
"payment_method_selected": "PAYPAL",
"brand_name": "Martin Henson Prints",
"locale": "en-GB",
"landing_page": "LOGIN",
"user_action": "PAY_NOW",
"shipping_preference": "SET_PROVIDED_ADDRESS",
}
},
"purchase_units": [{
"amount": {
"currency_code": "GBP",
"value": "{:.2f}".format(cart_total),
"breakdown": amount_breakdown
},
"items": items,
"shipping": {
"name": {
"full_name": f"{first_name} {last_name}"
},
"address": {
"address_line_1": f"{house} {street}",
"admin_area_2": city,
"postal_code": postcode,
"country_code": "GB"
}
}
}]
}
response = requests.post('https://api.sandbox.paypal.com/v2/checkout/orders', headers=headers, json=data)