I constantly get an error whenever I make a POST request to /api/tickets/:
Internal Server Error: /payment-stripe/
Traceback (most recent call last):
File "/ENV/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/ENV/lib/python3.8/site-packages/django/utils/deprecation.py", line 96, in __call__
response = self.process_response(request, response)
File "/ENV/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
if response.get('X-Frame-Options') is not None:
AttributeError: 'tuple' object has no attribute 'get'
[03/Jan/2020 03:17:09] "POST /payment-stripe/ HTTP/1.1" 500 58576
Here is my stripe payment handling view that I think is causing the problem, but I can't find out why:
@require_http_methods(["POST"])
@csrf_exempt
def stripe_payment_handling(request):
"""
The following code is copied from Stripe Docs.
Everything inside the IF statements is how the ticket gets handled.
"""
payload = request.body
# Checks for the signature of stripe.
sig_header = request.headers['Stripe-Signature']
event = None
try:
# Tests if it can create a connection with Stripe.
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# invalid payload: If it doesn't pass it gives back a 400
return "Invalid payload", 400
except stripe.error.SignatureVerificationError as e:
# invalid signature: If the Stripe Signature is not there it wont accept it.
return "Invalid signature", 400
# Create the a dictionary with the data
event_dict = event.to_dict()
print(event_dict)
if event_dict['type'] == "payment_intent.created":
# If someone redirects to the bank to pay it will create a payment intent
# Now it will use that value to validate the payment
intent = event_dict['data']['object']
ticket = Ticket.objects.get(
stripe_payment_intent=intent["id"]
)
ticket.status = "Created"
ticket.save()
elif event_dict['type'] == "payment_intent.succeeded":
# If the payment Succeeded:
intent = event_dict['data']['object']
# get the ticket with the intent id that was created from payment_intent.created
ticket = Ticket.objects.get(stripe_payment_intent=intent["id"])
# Change status to Completed
ticket.status = "Completed"
ticket.save()
# Reduce the amount of stock for the selected parking location
ticket.stock_type.quantity -= 1
ticket.stock_type.save()
# Send the email to the client
# The .send_ticket_email() function is part of the Ticket Model
ticket.send_ticket_email()
elif event_dict['type'] == "payment_intent.payment_failed":
# If the payment has failed:
intent = event_dict['data']['object']
# Get the error message
error_message = intent['last_payment_error']['message']
print("Failed: ", intent['id'], error_message)
# Notify the customer that payment failed
try:
# Find the ticket based on the intent id
ticket = Ticket.objects.get(stripe_payment_intent=intent["id"])
# Change its status to Failed
ticket.status = "Failed"
ticket.save()
# Send Failed email
# the .send_failed_email() function is part of the Ticket model
ticket.send_failed_email()
except Exception as e:
# if the payment intent wasn't found send an email to contact support:
print("Payment intent not found! => {0}".format(e))
elif event_dict['type'] == "payment_intent.canceled":
print("PAYMENT INTENT CANCELED")
elif event_dict['type'] == "payment_intent.amount_capturable_updated":
print("PAYMENT INTENT UPDATED")
else:
print("INTENT = {NONE}")
return HttpResponse(status=200)
(extra) Here is my api/views.py:
class TicketInitialize(generics.GenericAPIView):
queryset = Ticket.objects.all()
serializer_class = TicketSerializer
permission_classes = (permissions.AllowAny,)
def post(self, request, *args, **kwargs):
ticket_price = int(float(request.data["price"])) * 100
print(ticket_price)
stripe.api_key = 'my_stripe_api_key'
intent = stripe.PaymentIntent.create(
amount=ticket_price,
currency='eur',
payment_method_types=['card', 'ideal']
)
request.data["stripe_payment_intent"] = intent["id"]
stock = Stock.objects.get(id=request.data["stock_type"])
event = Event.objects.get(id=request.data["event"])
new_ticket = Ticket.objects.create(
first_name=request.data["first_name"],
last_name=request.data["last_name"],
quantity=request.data["quantity"],
cell_phone=request.data["cell_phone"],
email=request.data["email"],
price=request.data["price"],
service_fee=request.data["service_fee"],
stock_type=stock,
event=event,
stripe_payment_intent=request.data["stripe_payment_intent"]
)
return Response(intent)
my urls.py:
urlpatterns = [
path('payment-stripe/', views.stripe_payment_handling, name="stripe-endpoint"),
]
I don't understand why it keeps giving me the Attribute Error. It won't allow me to handle any webhooks from stripe or complete orders.
Thank you for taking a look, and I'm looking forward to your suggestions and answers!
Change return "Invalid signature", 400
to
return HttpResponse(status=400, content="Invalid signature")
and return "Invalid payload", 400
to
return HttpResponse(status=400, content="Invalid payload")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.