Order creation API: Allow to create orders without payment provider

This commit is contained in:
Raphael Michel
2019-08-14 09:22:58 +02:00
parent 5cda04a994
commit c2eba21359
3 changed files with 41 additions and 21 deletions
+6 -4
View File
@@ -141,7 +141,9 @@ last_modified datetime Last modificati
.. versionchanged:: 3.1:
The ``invoice_address.state`` attribute has been added.
The ``invoice_address.state`` attribute has been added. When creating orders through the API,
vouchers are now supported and many fields are now optional.
.. _order-position-resource:
@@ -754,9 +756,9 @@ Creating orders
* ``email``
* ``locale``
* ``sales_channel``
* ``payment_provider`` The identifier of the payment provider set for this order. This needs to be an existing
payment provider. You should use ``"free"`` for free orders, and we strongly advise to use ``"manual"`` for all
orders you create as paid.
* ``payment_provider`` (optional) The identifier of the payment provider set for this order. This needs to be an
existing payment provider. You should use ``"free"`` for free orders, and we strongly advise to use ``"manual"``
for all orders you create as paid.
* ``payment_info`` (optional) You can pass a nested JSON object that will be set as the internal ``info``
value of the payment object that will be created. How this value is handled is up to the payment provider and you
should only use this if you know the specific payment provider in detail. Please keep in mind that the payment
+6 -2
View File
@@ -555,7 +555,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
min_length=5
)
comment = serializers.CharField(required=False, allow_blank=True)
payment_provider = serializers.CharField(required=True)
payment_provider = serializers.CharField(required=False, allow_null=True)
payment_info = CompatibleJSONField(required=False)
consume_carts = serializers.ListField(child=serializers.CharField(), required=False)
force = serializers.BooleanField(default=False, required=False)
@@ -573,6 +573,8 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
'force', 'send_mail')
def validate_payment_provider(self, pp):
if pp is None:
return None
if pp not in self.context['event'].get_payment_providers():
raise ValidationError('The given payment provider is not known.')
return pp
@@ -642,7 +644,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
def create(self, validated_data):
fees_data = validated_data.pop('fees') if 'fees' in validated_data else []
positions_data = validated_data.pop('positions') if 'positions' in validated_data else []
payment_provider = validated_data.pop('payment_provider')
payment_provider = validated_data.pop('payment_provider', None)
payment_info = validated_data.pop('payment_info', '{}')
payment_date = validated_data.pop('payment_date', now())
force = validated_data.pop('force', False)
@@ -832,6 +834,8 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
elif payment_provider == "free" and order.total != Decimal('0.00'):
raise ValidationError('You cannot use the "free" payment provider for non-free orders.')
elif validated_data.get('status') == Order.STATUS_PAID:
if not payment_provider:
raise ValidationError('You cannot create a paid order without a payment provider.')
order.payments.create(
amount=order.total,
provider=payment_provider,
+29 -15
View File
@@ -2495,21 +2495,6 @@ def test_order_create_free(token_client, organizer, event, item, quota, question
assert p.state == "confirmed"
@pytest.mark.django_db
def test_order_create_require_payment_provider(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
del res['payment_provider']
res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 400
assert resp.data == {'payment_provider': ['This field is required.']}
@pytest.mark.django_db
def test_order_create_invalid_payment_provider(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
@@ -2853,6 +2838,35 @@ def test_order_create_send_emails_paid(token_client, organizer, event, item, quo
assert djmail.outbox[1].subject == "Payment received for your order: {}".format(resp.data['code'])
@pytest.mark.django_db
def test_order_paid_require_payment_method(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk
del res['payment_provider']
res['status'] = 'p'
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 400
assert resp.data == [
'You cannot create a paid order without a payment provider.'
]
res['status'] = "n"
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code'])
assert not o.payments.exists()
@pytest.mark.django_db
def test_order_create_auto_pricing(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)