英文:
success_url working on local but does not on production
问题
我有一个使用Stripe进行支付的Django网站。在我的本地终端和生产服务器上,一切似乎都正常工作。但是,在部署的网站上,我的成功页面返回了Bad Request(400)。我将展示下面的代码。
调用success_url的方法
def charges(request, order_id):
try:
cart_items = CartItem.objects.filter(user=request.user)
domain = settings.DOMAIN_NAME
if settings.DEBUG:
domain = "http://127.0.0.1:8000/"
session = stripe.checkout.Session.create(
customer_email=request.user.email,
payment_method_types=['card'],
line_items=[{
'price_data': {
'product_data': {
'name': cart_item.product.product_name,
},
'unit_amount_decimal': cart_item.product.price*100,
'currency': 'usd',
},
'quantity': cart_item.quantity,
'tax_rates': [tax_rate.id],
} for cart_item in cart_items],
metadata={
"orderID": order_id
},
mode='payment',
success_url=domain + 'orders/order_complete?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain + 'orders/order_incomplete?session_id={CHECKOUT_SESSION_ID}',
)
# Pass the session ID to the template
return JsonResponse({
"id": session.id
})
except stripe.error.InvalidRequestError as e:
# 处理特定的InvalidRequestError异常
print(f"无效的请求错误: {e.param}")
except stripe.error.StripeError as e:
# 处理其他与Stripe相关的错误
print(f"Stripe错误: {e}")
except stripe.error.ValueError as e:
print(f"Stripe错误: {e}")
except Exception as e:
# 处理其他常见异常
return JsonResponse({'error': str(e)})
呈现成功页面的方法
def order_complete(request):
session_id = request.GET.get('session_id')
session = stripe.checkout.Session.retrieve(session_id)
order_number = session["metadata"]["orderID"]
transID = session["id"]
try:
order = Order.objects.get(order_number=order_number, is_ordered=True)
ordered_products = OrderProduct.objects.filter(order_id=order.id)
payment = Payment.objects.get(payment_id=transID)
context = {
'order': order,
'ordered_products': ordered_products,
'order_number': order.order_number,
'transID': payment.payment_id,
'payment': payment,
}
return render(request, "orders/order_complete.html", context)
except (Payment.DoesNotExist, Order.DoesNotExist):
return redirect('home')
order_complete.html
{% block content %}
<div class="container" style="margin-top: 50px; text-align:center">
<i class="fas fa-check-circle" style="font-size: 72px;margin-bottom: 20px;color: #28A745;"></i>
<h2 class="text-center">Payment Successful</h2>
<br>
<div class="text-center">
<a href="{% url 'store' %}" class="btn btn-success">Shop more</a>
</div>
</div>
<div class="container" style="margin: 0 auto;width: 50%;padding: 50px;background: #f1f1f1;margin-top: 50px;margin-bottom: 50px;">
<div class="row invoice row-printable">
<div class="col-md-12">
<!-- col-lg-12 start here -->
<div class="panel panel-default plain" id="dash_0">
<!-- Start .panel -->
<div class="panel-body p30">
<div class="row">
<!-- Start .row -->
<div class="col-lg-6">
<!-- col-lg-6 start here -->
<div class="invoice-logo"><img src="{% static '/images/logo.png' %}" alt="Invoice logo" style="max-height: 40px;"></div>
</div>
<!-- col-lg-6 end here -->
<div class="col-lg-6">
<!-- col-lg-6 start here -->
<div class="invoice-from">
<ul class="list-unstyled text-right">
<li><strong>Invoiced To</strong></li>
<li>{{order.full_name}}</li>
<li>{{order.full_address}}</li>
<li>{{order.city}}, {{order.state}} {{order.zip}}</li>
</ul>
</div>
</div>
<!-- col-lg-6 end here -->
<div class="col-lg-12">
<!-- col-lg-12 start here -->
<div class="invoice-details mt25">
<div class="well">
<ul class="list-unstyled mb0">
<li><strong>Order:</strong> #{{order_number}}</li>
<li><strong>Transaction ID:</strong> {{transID}}</li>
<li><strong>Order Date:</strong> {{order.created_at}}</li>
<li><strong>Status:</strong> {{order.status}}</li>
</ul>
</div>
</div>
<div class="invoice-items">
<div class="table-responsive" style="overflow: hidden; outline: none;" tabindex="0">
<table class="table table-bordered">
<thead>
<tr>
<th class="per70 text-center">Products</th>
<th class="per5 text-center">Qty</th>
<th class="per25 text-center">Total</th>
</tr>
</thead>
<tbody>
{% for item in ordered_products %}
<tr>
<td>{{item.product.product_name}}
<p class="text-muted small">
{% if item.variations.all %}
{% for i in item.variations.all %}
{{ i.variation_category | capfirst }} : {{ i.variation_value | capfirst }} <br>
{% endfor %}
{% endif %}
</p>
</td>
<td class="text-center">{{item.quantity}}</td>
<td class="text-center">${{item.product_price}}</td>
</tr>
{% endfor %}
<details>
<summary>英文:</summary>
I have a django website which uses stripe for payment. Everything seems to work fine on my local terminal and production server. However, my success page on the deployed website returns a **Bad Request(400)**. I'll show the code below.
The method that calls the success_url
def charges(request, order_id):
try:
cart_items = CartItem.objects.filter(user=request.user)
domain = settings.DOMAIN_NAME
if settings.DEBUG:
domain = "http://127.0.0.1:8000/"
session = stripe.checkout.Session.create(
customer_email=request.user.email,
payment_method_types=['card'],
line_items=[{
'price_data': {
'product_data': {
'name': cart_item.product.product_name,
},
'unit_amount_decimal': cart_item.product.price*100,
'currency': 'usd',
},
'quantity': cart_item.quantity,
'tax_rates': [tax_rate.id],
} for cart_item in cart_items],
metadata={
"orderID": order_id
},
mode='payment',
success_url=domain + 'orders/order_complete?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain + 'orders/order_incomplete?session_id={CHECKOUT_SESSION_ID}',
)
# Pass the session ID to the template
return JsonResponse({
"id": session.id
})
except stripe.error.InvalidRequestError as e:
# Handle the specific InvalidRequestError exception
print(f"Invalid request error: {e.param}")
except stripe.error.StripeError as e:
# Handle other Stripe-related errors
print(f"Stripe error: {e}")
except stripe.error.ValueError as e:
print(f"Stripe error: {e}")
except Exception as e:
# Handle other general exceptions
return JsonResponse({'error': str(e)})
The method that renders the success page
def order_complete(request):
session_id = request.GET.get('session_id')
session = stripe.checkout.Session.retrieve(session_id)
order_number = session["metadata"]["orderID"]
transID = session["id"]
try:
order = Order.objects.get(order_number=order_number, is_ordered=True)
ordered_products = OrderProduct.objects.filter(order_id=order.id)
payment = Payment.objects.get(payment_id=transID)
context = {
'order': order,
'ordered_products': ordered_products,
'order_number': order.order_number,
'transID': payment.payment_id,
'payment': payment,
}
return render(request, "orders/order_complete.html", context)
except (Payment.DoesNotExist, Order.DoesNotExist):
return redirect('home')
order_complete.html
{% block content %}
<div class="container" style="margin-top: 50px; text-align:center">
<i class="fas fa-check-circle" style="font-size: 72px;margin-bottom: 20px;color: #28A745;"></i>
<h2 class="text-center">Payment Successful</h2>
<br>
<div class="text-center">
<a href="{% url 'store' %}" class="btn btn-success">Shop more</a>
</div>
</div>
<div class="container" style="margin: 0 auto;width: 50%;padding: 50px;background: #f1f1f1;margin-top: 50px;margin-bottom: 50px;">
<div class="row invoice row-printable">
<div class="col-md-12">
<!-- col-lg-12 start here -->
<div class="panel panel-default plain" id="dash_0">
<!-- Start .panel -->
<div class="panel-body p30">
<div class="row">
<!-- Start .row -->
<div class="col-lg-6">
<!-- col-lg-6 start here -->
<div class="invoice-logo"><img src="{% static '/images/logo.png' %}" alt="Invoice logo" style="max-height: 40px;"></div>
</div>
<!-- col-lg-6 end here -->
<div class="col-lg-6">
<!-- col-lg-6 start here -->
<div class="invoice-from">
<ul class="list-unstyled text-right">
<li><strong>Invoiced To</strong></li>
<li>{{order.full_name}}</li>
<li>{{order.full_address}}</li>
<li>{{order.city}}, {{order.state}} {{order.zip}}</li>
</ul>
</div>
</div>
<!-- col-lg-6 end here -->
<div class="col-lg-12">
<!-- col-lg-12 start here -->
<div class="invoice-details mt25">
<div class="well">
<ul class="list-unstyled mb0">
<li><strong>Order:</strong> #{{order_number}}</li>
<li><strong>Transaction ID:</strong> {{transID}}</li>
<li><strong>Order Date:</strong> {{order.created_at}}</li>
<li><strong>Status:</strong> {{order.status}}</li>
</ul>
</div>
</div>
<div class="invoice-items">
<div class="table-responsive" style="overflow: hidden; outline: none;" tabindex="0">
<table class="table table-bordered">
<thead>
<tr>
<th class="per70 text-center">Products</th>
<th class="per5 text-center">Qty</th>
<th class="per25 text-center">Total</th>
</tr>
</thead>
<tbody>
{% for item in ordered_products %}
<tr>
<td>{{item.product.product_name}}
<p class="text-muted small">
{% if item.variations.all %}
{% for i in item.variations.all %}
{{ i.variation_category | capfirst }} : {{ i.variation_value | capfirst }} <br>
{% endfor %}
{% endif %}
</p>
</td>
<td class="text-center">{{item.quantity}}</td>
<td class="text-center">${{item.product_price}}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th colspan="2" class="text-right">Sub Total:</th>
<th class="text-center">${{order.sub_total}} </th>
</tr>
<tr>
<th colspan="2" class="text-right">Tax:</th>
<th class="text-center">${{order.tax}} </th>
</tr>
<tr>
<th colspan="2" class="text-right">Order Total:</th>
<th class="text-center">${{order.order_total}} </th>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="invoice-footer mt25">
<p class="text-center">Thank you for shopping with us!</p>
</div>
</div>
<!-- col-lg-12 end here -->
</div>
<!-- End .row -->
</div>
</div>
<!-- End .panel -->
</div>
<!-- col-lg-12 end here -->
</div>
</div>
{% endblock content %}
While testing after being redirected to the stripe checkout page and successfully paying for a product, the success_url takes me to the order_complete page where I access attributes of the checkout session. However, in production, I'm with the image below.
[success_url page](https://i.stack.imgur.com/vPWUR.png)
I'm using aws elastic beanstalk for deployment if that helps. My webhook is also properly connected and catches all events. The success page just refuses to load.
</details>
# 答案1
**得分**: 0
你应该使用reverse_lazy来生成success_url。
假设你在urls.py中的URL名称是"order_complete",代码应该是:
```python
success_url = reverse_lazy("order_complete", kwargs={'session_id': CHECKOUT_SESSION_ID})
参考链接:https://docs.djangoproject.com/en/4.2/ref/urlresolvers/
英文:
You should use reverse_lazy to generate success_url.
Assuming your url name in urls.py is "order_complete"
code should be:
success_url = reverse_lazy("order_complete", kwargs={'session_id': CHECKOUT_SESSION_ID})
reference : https://docs.djangoproject.com/en/4.2/ref/urlresolvers/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论