success_url 在本地工作,但在生产环境上不起作用。

huangapple go评论69阅读模式
英文:

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&#39;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 = {
&#39;order&#39;: order,
&#39;ordered_products&#39;: ordered_products,
&#39;order_number&#39;: order.order_number,
&#39;transID&#39;: payment.payment_id,
&#39;payment&#39;: payment,
}
return render(request, &quot;orders/order_complete.html&quot;, 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>

                        &lt;div class=&quot;invoice-items&quot;&gt;
&lt;div class=&quot;table-responsive&quot; style=&quot;overflow: hidden; outline: none;&quot; tabindex=&quot;0&quot;&gt;
&lt;table class=&quot;table table-bordered&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;per70 text-center&quot;&gt;Products&lt;/th&gt;
&lt;th class=&quot;per5 text-center&quot;&gt;Qty&lt;/th&gt;
&lt;th class=&quot;per25 text-center&quot;&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
{% for item in ordered_products %}
&lt;tr&gt;
&lt;td&gt;{{item.product.product_name}}
&lt;p class=&quot;text-muted small&quot;&gt;
{% if item.variations.all %}
{% for i in item.variations.all %}
{{ i.variation_category | capfirst }} : {{ i.variation_value | capfirst }} &lt;br&gt;
{% endfor %}
{% endif %}
&lt;/p&gt;
&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;{{item.quantity}}&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;${{item.product_price}}&lt;/td&gt;
&lt;/tr&gt;
{% endfor %}
&lt;/tbody&gt;
&lt;tfoot&gt;
&lt;tr&gt;
&lt;th colspan=&quot;2&quot; class=&quot;text-right&quot;&gt;Sub Total:&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;${{order.sub_total}} &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th colspan=&quot;2&quot; class=&quot;text-right&quot;&gt;Tax:&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;${{order.tax}} &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th colspan=&quot;2&quot; class=&quot;text-right&quot;&gt;Order Total:&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;${{order.order_total}} &lt;/th&gt;
&lt;/tr&gt;
&lt;/tfoot&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;invoice-footer mt25&quot;&gt;
&lt;p class=&quot;text-center&quot;&gt;Thank you for shopping with us!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- col-lg-12 end here --&gt;
&lt;/div&gt;
&lt;!-- End .row --&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;!-- End .panel --&gt;
&lt;/div&gt;
&lt;!-- col-lg-12 end here --&gt;
&lt;/div&gt;
&lt;/div&gt;

{% 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&#39;m with the image below.
[success_url page](https://i.stack.imgur.com/vPWUR.png)
I&#39;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(&quot;order_complete&quot;, kwargs={&#39;session_id&#39;: CHECKOUT_SESSION_ID})

reference : https://docs.djangoproject.com/en/4.2/ref/urlresolvers/

huangapple
  • 本文由 发表于 2023年6月19日 12:48:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76503669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定