lingo: handle single basket item payment (#25725)
This commit is contained in:
parent
13bbfa8bf1
commit
a7076e6e18
|
@ -21,7 +21,7 @@ from combo.urls_utils import decorated_includes, manager_required
|
|||
from .views import (RegiesApiView, AddBasketItemApiView, PayView, CallbackView,
|
||||
ReturnView, ItemDownloadView, ItemView, CancelItemView,
|
||||
RemoveBasketItemApiView, ValidateTransactionApiView,
|
||||
CancelTransactionApiView, SelfInvoiceView)
|
||||
CancelTransactionApiView, SelfInvoiceView, BasketItemPayView)
|
||||
from .manager_views import (RegieListView, RegieCreateView, RegieUpdateView,
|
||||
RegieDeleteView, TransactionListView, download_transactions_csv)
|
||||
|
||||
|
@ -56,6 +56,8 @@ urlpatterns = [
|
|||
ItemDownloadView.as_view(), name='download-item-pdf'),
|
||||
url(r'^lingo/item/(?P<regie_id>[\w,-]+)/(?P<item_crypto_id>[\w,-]+)/$',
|
||||
ItemView.as_view(), name='view-item'),
|
||||
url(r'^lingo/item/(?P<item_id>\d+)/pay$',
|
||||
BasketItemPayView.as_view(), name='basket-item-pay-view'),
|
||||
url(r'^lingo/self-invoice/(?P<cell_id>\w+)/$', SelfInvoiceView.as_view(),
|
||||
name='lingo-self-invoice'),
|
||||
]
|
||||
|
|
|
@ -24,7 +24,7 @@ from django.contrib.auth.models import User
|
|||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.http import HttpResponseForbidden, Http404
|
||||
from django.http import HttpResponseForbidden, Http404, JsonResponse
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import force_text
|
||||
|
@ -164,9 +164,9 @@ class AddBasketItemApiView(View):
|
|||
item.save()
|
||||
item.regie.compute_extra_fees(user=item.user)
|
||||
|
||||
response = HttpResponse(content_type='application/json')
|
||||
response.write(json.dumps({'result': 'success', 'id': str(item.id)}))
|
||||
return response
|
||||
payment_url = reverse('basket-item-pay-view', kwargs={'item_id': item.id})
|
||||
return JsonResponse({'result': 'success', 'id': str(item.id),
|
||||
'payment_url': request.build_absolute_uri(payment_url)})
|
||||
|
||||
|
||||
class RemoveBasketItemApiView(View):
|
||||
|
@ -391,6 +391,23 @@ class PayView(PayMixin, View):
|
|||
return self.handle_payment(request, regie, items, remote_items, next_url, email)
|
||||
|
||||
|
||||
class BasketItemPayView(PayMixin, View):
|
||||
def get(self, request, *args, **kwargs):
|
||||
next_url = request.GET.get('next_url') or '/'
|
||||
if not (request.user and request.user.is_authenticated()):
|
||||
return HttpResponseForbidden(_('No item payment allowed for anonymous users.'))
|
||||
|
||||
item = BasketItem.objects.get(pk=kwargs['item_id'])
|
||||
regie = item.regie
|
||||
if regie.extra_fees_ws_url:
|
||||
return HttpResponseForbidden(_('No item payment allowed as extra fees set.'))
|
||||
|
||||
if item.user != request.user:
|
||||
return HttpResponseForbidden(_('Wrong item: payment not allowed.'))
|
||||
|
||||
return self.handle_payment(request, regie, [item], [], next_url)
|
||||
|
||||
|
||||
class PaymentException(Exception):
|
||||
pass
|
||||
|
||||
|
|
|
@ -199,8 +199,11 @@ def test_add_amount_to_basket(app, key, regie, user):
|
|||
url = '%s?email=%s&orig=wcs' % (reverse('api-add-basket-item'), user_email)
|
||||
url = sign_url(url, settings.LINGO_API_SIGN_KEY)
|
||||
resp = app.post_json(url, params=data)
|
||||
item = BasketItem.objects.get(amount=Decimal('22.23'))
|
||||
assert resp.status_code == 200
|
||||
assert json.loads(resp.content)['result'] == 'success'
|
||||
response = json.loads(resp.content)
|
||||
assert response['result'] == 'success'
|
||||
assert response['payment_url'].endswith('/lingo/item/%s/pay' % item.id)
|
||||
assert BasketItem.objects.filter(amount=Decimal('22.23')).exists()
|
||||
assert BasketItem.objects.filter(amount=Decimal('22.23'))[0].regie_id == other_regie.id
|
||||
|
||||
|
@ -230,6 +233,58 @@ def test_add_amount_to_basket(app, key, regie, user):
|
|||
resp = app.post_json(url, params=data, status=400)
|
||||
assert resp.text == 'Unknown regie'
|
||||
|
||||
def test_pay_single_basket_item(app, key, regie, user, john_doe):
|
||||
page = Page(title='xxx', slug='index', template_name='standard')
|
||||
page.save()
|
||||
cell = LingoBasketCell(page=page, placeholder='content', order=0)
|
||||
cell.save()
|
||||
|
||||
amount = 12
|
||||
data = {'amount': amount,
|
||||
'display_name': 'test amount',
|
||||
'url': 'http://example.com'}
|
||||
url = '%s?email=%s&orig=wcs' % (reverse('api-add-basket-item'), user.email)
|
||||
url = sign_url(url, key)
|
||||
resp = app.post_json(url, params=data)
|
||||
# check that an unpaid item exists in basket
|
||||
assert BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=True).exists()
|
||||
payment_url = resp.json['payment_url']
|
||||
resp = app.get(payment_url, status=403)
|
||||
assert 'No item payment allowed for anonymous users.' in resp.text
|
||||
|
||||
login(app, username='john.doe', password='john.doe')
|
||||
resp = app.get(payment_url, status=403)
|
||||
assert 'Wrong item: payment not allowed.' in resp.text
|
||||
|
||||
# forbid payment to regie with extra_fees_ws_url
|
||||
regie.extra_fees_ws_url = 'http://example.com/extra-fees'
|
||||
regie.save()
|
||||
app.reset()
|
||||
login(app)
|
||||
resp = app.get(payment_url, status=403)
|
||||
assert 'No item payment allowed as extra fees set.' in resp.text
|
||||
|
||||
regie.extra_fees_ws_url = ''
|
||||
regie.save()
|
||||
|
||||
resp = app.get(payment_url, params={'next_url': 'http://example.net/form/id/'})
|
||||
|
||||
# make sure the redirection is done to the payment backend
|
||||
assert resp.location.startswith('http://dummy-payment.demo.entrouvert.com/')
|
||||
qs = urlparse.parse_qs(urlparse.urlparse(resp.location).query)
|
||||
assert qs['amount'] == ['12.00']
|
||||
|
||||
# simulate successful payment response from dummy backend
|
||||
data = {'transaction_id': qs['transaction_id'][0], 'ok': True,
|
||||
'amount': qs['amount'][0], 'signed': True}
|
||||
# simulate payment service redirecting the user to /lingo/return/... (eopayment
|
||||
# dummy module put that URL in return_url query string parameter).
|
||||
resp = app.get(qs['return_url'][0], params=data)
|
||||
# check that item is paid
|
||||
assert BasketItem.objects.filter(regie=regie, amount=amount, payment_date__isnull=False).exists()
|
||||
# check that user is redirected to the next_url passed previously
|
||||
assert resp.location == 'http://example.net/form/id/'
|
||||
|
||||
def test_pay_multiple_regies(app, key, regie, user):
|
||||
test_add_amount_to_basket(app, key, regie, user)
|
||||
|
||||
|
|
Loading…
Reference in New Issue