html - 使用braintree,Django时错误类型对象'配置'没有属性'环境'
问题描述
我正在尝试通过 Antiono Mele 编写的“Django 3 by example”一书来学习 Django,但在使用 Braintree 时,我遇到了沙盒环境配置的问题。在他们的页面上写着:
gateway = braintree.BraintreeGateway(
braintree.Configuration(
environment=braintree.Environment.Sandbox,
merchant_id='**********',
public_key='**********',
private_key='**********'
)
)
和书中的一模一样。当我尝试付款时Error type object 'Configuration' has no attribute 'environment'。我不知道为什么会出现错误。我检查了我使用的应用程序版本,它们与书中的版本相匹配(Pillow==7.0.0.、Django==3.1.8、celery==4.4.2、 braintree==3.59.0)。下面我放了需要的代码。
付款/views.py
import braintree
from django.shortcuts import render, redirect, get_object_or_404
from orders.models import Order
gateway = braintree.BraintreeGateway(
braintree.Configuration(
environment=braintree.Environment.Sandbox,
merchant_id='**********',
public_key='**********',
private_key='**********'
)
)
# Utworzenie egzemplarza bramki płatności Braintree.
def payment_process(request):
order_id = request.session.get('order_id')
order = get_object_or_404(Order, id=order_id)
if request.method == 'POST':
# Pobranie tokena nonce.
nonce = request.POST.get('payment_method_nonce', None)
# Utworzenie i przesłanie transakcji.
result = braintree.Transaction.sale({
'amount': '{:.2f}'.format(order.get_total_cost()),
'payment_method_nonce': nonce,
'options': {
'submit_for_settlement': True
}
})
if result.is_success:
# Oznaczenie zamówienia jako opłacone.
order.paid = True
# Zapisanie unikatowego identyfikatora transakcji.
order.braintree_id = result.transaction.id
order.save()
return redirect('payment:done')
else:
return redirect('payment:canceled')
else:
# Wygenerowanie tokena.
client_token = braintree.ClientToken.generate()
return render(request,
'payment/process.html',
{'order': order,
'client_token': client_token})
def payment_done(request):
return render(request, 'payment/done.html')
def payment_canceled(request):
return render(request, 'payment/canceled.html') ```
myshop/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('cart/', include('cart.urls', namespace='cart')),
path('orders/', include('orders.urls', namespace='orders')),
path('payment/', include('payment.urls', namespace='payment')),
path('', include('shop.urls', namespace='shop')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
付款/模板/付款/process.html
{% extends "shop/base.html" %}
{% block title %}Zapłać kartą kredytową{% endblock %}
{% block content %}
<h1>Zapłać kartą kredytową</h1>
<form action="." id="payment" method="post">
<label for="card-number">Numer karty</label>
<div id="card-number" class="field"></div>
<label for="cvv">CVV</label>
<div id="cvv" class="field"></div>
<label for="expiration-date">Data ważności</label>
<div id="expiration-date" class="field"></div>
<input type="hidden" id="nonce" name="payment_method_nonce" value="">
{% csrf_token %}
<input type="submit" value="Pay">
</form>
<!-- Załadowanie wymaganych komponentów klienta. -->
<script
src="https://js.braintreegateway.com/web/3.29.0/js/client.min.js"></script>
<!-- Załadowanie komponentu Hosted Fields. -->
<script src="https://js.braintreegateway.com/web/3.29.0/js/hosted-fields.min.js"></script>
<script>
var form = document.querySelector('#payment');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '{{ client_token }}'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {'font-size': '13px'},
'input.invalid': {'color': 'red'},
'input.valid': {'color': 'green'}
},
fields: {
number: {selector: '#card-number'},
cvv: {selector: '#cvv'},
expirationDate: {selector: '#expiration-date'}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
// Ustawienie tokena nonce w celu przesłania na serwer.
document.getElementById('nonce').value = payload.nonce;
// Przesłanie formularza.
document.getElementById('payment').submit();
});
}, false);
});
});
</script>
{% endblock %}
此致。
解决方案
我知道这有点晚了,但也许将来有人会需要它。
更改自:
gateway = braintree.BraintreeGateway(
braintree.Configuration(
environment=braintree.Environment.Sandbox,
merchant_id='**********',
public_key='**********',
private_key='**********'
)
)
至:
gateway = braintree.BraintreeGateway(
braintree.Configuration.configure(
environment=braintree.Environment.Sandbox,
merchant_id='**********',
public_key='**********',
private_key='**********'
)
)
推荐阅读
- html - 在经典 ASP 中向 AJAX 添加参数
- spring - Spring Cloud Consul 配置版本控制
- c++ - 具有 emplace-mechanisms 的 stdlib 类应该是友好的吗?
- arrays - 如何识别 Swift 数组中特定值的连续出现?
- uno-platform - 如何将类库项目添加到 Uno-Platform?
- asp.net-mvc - 为 ASP.NET MVC 5 项目设计更复杂的数据库
- java - 是否可以强制转换方法?
- swift - 插入的模型看起来比预期的大并且在相机的背面
- python - 使用 Keras 的慢 DQN
- python - 如何将具有每日收益的数据框转换为从 100 开始的数据框索引