试图从失败的Stripe充电中获取错误

时间:2017-03-09 20:51:50

标签: django python-3.x stripe-payments

我设置了一个简单的条带支付来玩,我可以成功地为卡充电但是当它失败时我得到一个带有'CardError'对象的AttributeError没有属性'messages'而不是html页面上的错误消息。

在我的模型中,我收到条带费用并返回一个元组,其中包含费用的成功以及收费或错误消息的详细信息。

#models.py

class Sale(models.Model):
def __init__(self, *args, **kwargs):
    super(Sale, self).__init__(*args, **kwargs)

    import stripe
    stripe.api_key = settings.STRIPE_SECRET_KEY
    self.stripe = stripe

customer = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
charge_id = models.CharField(max_length=32)



def charge(self, price_in_cents, number, exp_month, exp_year, cvc, address_zip):

    if self.charge_id:
        return False, Exception(message='This charge has already been issued.')

    try:
        response = self.stripe.Charge.create(
            amount = price_in_cents,
            currency = 'usd',
            card = {
                'number': number,
                'exp_month': exp_month,
                'exp_year': exp_year,
                'cvc': cvc,
                'address_zip': address_zip,
            },
            description = 'Thank you for signing up for our program.')
        self.charge_id = response.id
        self.customer = request.user

    except self.stripe.error.CardError as ce:
        return False, ce
    except Exception as e:
        return False, e

    return True, response

我的表单会设置该字段并从模型中获取费用。

#forms.py

class SalePaymentForm(forms.Form):
    number = CreditCardField(required=True, label="Card Number")
    expiration = CCExpField(required=True, label="Expiration")
    cvc = forms.IntegerField(required=True, label="CCV Number", max_value=9999, widget=forms.TextInput(attrs={'size': '4'}))
    address_zip = forms.IntegerField(required=True, label='Address Zip Code', max_value=99999, widget=forms.TextInput(attrs={'size': '5'}))

def clean(self):
    cleaned = super(SalePaymentForm, self).clean()

    if not self.errors:
        number = self.cleaned_data['number']
        exp_month = self.cleaned_data['expiration'].month
        exp_year = self.cleaned_data['expiration'].year
        cvc = self.cleaned_data['cvc']
        address_zip = self.cleaned_data['address_zip']

        sale = Sale()

        success, instance = sale.charge(2500, number, exp_month, exp_year, cvc, address_zip)

        if not success:
            raise forms.ValidationError('Error: %s' % (instance.messages))
        else:
            instance.save()
            # Send Email
            pass

    return cleaned

我的视图只显示表单,然后转到成功页面或重新加载表单。

#views.py

def charge(request):
if request.method == "POST":
    form = SalePaymentForm(request.POST)

    if form.is_valid(): # charges the card
        return HttpResponse('Success!')
else:
    form = SalePaymentForm()

return render(request, 'sales.html', {'form': form})

以下是sales.html

的html模板

#sales.html

<html>
<head>
  <title>Stripe Example</title>
</head>
<body>
 
<div class="wrapper">
 
  {% for key, value in form.errors.items %}
      <p>{{ value }}</p>
  {% endfor %}
 
  <form action="" method="post">{% csrf_token %}
 
    {% for field in form %}
      <div class="field-wrapper">
 
        <div class="field-label">
          {{ field.label_tag }}:
        </div>
 
        <div class="field-field">
          {{ field }}
          {{ field.errors }}
        </div>
 
      </div>
    {% endfor %}
 
    <br>
    <input type="submit" value="Charge Me!" />
  </form>
 
</div>
 
</body>
</html>

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

抛出的异常没有messages属性。 messages属性仅适用于Django的ValidationError类型异常及其子类。要处理Stripe的错误,请参阅以下示例:

try:
  # Use Stripe's library to make requests...
  pass
except stripe.error.CardError as e:
  # Since it's a decline, stripe.error.CardError will be caught
  body = e.json_body
  err  = body['error']

https://stripe.com/docs/api/python#errors