def webhook(request, *args, **kwargs): event_json = json.loads(request.body.decode('utf-8')) # We do not check for the event type as we are not interested in the event it self, # we just use it as a trigger to look the charge up to be absolutely sure. # Another reason for this is that stripe events are not authenticated, so they could # come from anywhere. if event_json['data']['object']['object'] == "charge": charge_id = event_json['data']['object']['id'] elif event_json['data']['object']['object'] == "dispute": charge_id = event_json['data']['object']['charge'] else: return HttpResponse("Not interested in this data type", status=200) prov = Stripe(request.event) prov._init_api() try: charge = stripe.Charge.retrieve(charge_id) except stripe.error.StripeError: logger.exception('Stripe error on webhook. Event data: %s' % str(event_json)) return HttpResponse('Charge not found', status=500) metadata = charge['metadata'] if 'event' not in metadata: return HttpResponse('Event not given in charge metadata', status=200) if int(metadata['event']) != request.event.pk: return HttpResponse('Not interested in this event', status=200) try: order = request.event.orders.get(id=metadata['order']) except Order.DoesNotExist: return HttpResponse('Order not found', status=200) order.log_action('pretix.plugins.stripe.event', data=event_json) is_refund = charge['refunds']['total_count'] or charge['dispute'] if order.status == Order.STATUS_PAID and is_refund: mark_order_refunded(order, user=None) elif order.status == Order.STATUS_PENDING and charge['status'] == 'succeeded' and not is_refund: mark_order_paid(order, user=None) return HttpResponse(status=200)
def webhook(request): event_json = json.loads(request.body.decode('utf-8')) event_type = event_json['type'] if event_type != 'charge.refunded': # Not interested return HttpResponse('Event is not a refund', status=200) charge = event_json['data']['object'] if charge['object'] != 'charge': return HttpResponse('Object is not a charge', status=200) metadata = charge['metadata'] if 'event' not in metadata: return HttpResponse('Event not given', status=200) try: event = Event.objects.get(id=metadata['event']) except Event.DoesNotExist: return HttpResponse('Event not found', status=200) try: order = Order.objects.get(id=metadata['order']) except Order.DoesNotExist: return HttpResponse('Order not found', status=200) prov = Stripe(event) prov._init_api() order.log_action('pretix.plugins.stripe.event', data=event_json) try: charge = stripe.Charge.retrieve(charge['id']) except stripe.error.StripeError as err: logger.error('Stripe error on webhook: %s Event data: %s' % (str(err), str(event_json))) return HttpResponse('StripeError', status=500) if charge['refunds'][ 'total_count'] > 0 and order.status == Order.STATUS_PAID: mark_order_refunded(order) return HttpResponse(status=200)
def webhook(request, *args, **kwargs): event_json = json.loads(request.body.decode('utf-8')) # We do not check for the event type as we are not interested in the event it self, # we just use it as a trigger to look the charge up to be absolutely sure. # Another reason for this is that stripe events are not authenticated, so they could # come from anywhere. if event_json['data']['object']['object'] == "charge": charge_id = event_json['data']['object']['id'] elif event_json['data']['object']['object'] == "dispute": charge_id = event_json['data']['object']['charge'] else: return HttpResponse("Not interested in this data type", status=200) prov = Stripe(request.event) prov._init_api() try: charge = stripe.Charge.retrieve(charge_id) except stripe.error.StripeError: logger.exception('Stripe error on webhook. Event data: %s' % str(event_json)) return HttpResponse('Charge not found', status=500) metadata = charge['metadata'] if 'event' not in metadata: return HttpResponse('Event not given in charge metadata', status=200) if int(metadata['event']) != request.event.pk: return HttpResponse('Not interested in this event', status=200) try: order = request.event.orders.get(id=metadata['order']) except Order.DoesNotExist: return HttpResponse('Order not found', status=200) order.log_action('pretix.plugins.stripe.event', data=event_json) if order.status == Order.STATUS_PAID and (charge['refunds']['total_count'] or charge['dispute']): mark_order_refunded(order, user=None) return HttpResponse(status=200)
def webhook(request): event_json = json.loads(request.body.decode('utf-8')) event_type = event_json['type'] if event_type != 'charge.refunded': # Not interested return HttpResponse('Event is not a refund', status=200) charge = event_json['data']['object'] if charge['object'] != 'charge': return HttpResponse('Object is not a charge', status=200) metadata = charge['metadata'] if 'event' not in metadata: return HttpResponse('Event not given', status=200) try: event = Event.objects.get(id=metadata['event']) except Event.DoesNotExist: return HttpResponse('Event not found', status=200) try: order = Order.objects.get(id=metadata['order']) except Order.DoesNotExist: return HttpResponse('Order not found', status=200) prov = Stripe(event) prov._init_api() order.log_action('pretix.plugins.stripe.event', data=event_json) try: charge = stripe.Charge.retrieve(charge['id']) except stripe.error.StripeError as err: logger.error('Stripe error on webhook: %s Event data: %s' % (str(err), str(event_json))) return HttpResponse('StripeError', status=500) if charge['refunds']['total_count'] > 0 and order.status == Order.STATUS_PAID: mark_order_refunded(order) return HttpResponse(status=200)
def test_perform_success(env, factory, monkeypatch): event, order = env def charge_create(**kwargs): assert kwargs['amount'] == 1337 assert kwargs['currency'] == 'eur' assert kwargs['source'] == 'tok_189fTT2eZvKYlo2CvJKzEzeu' c = MockedCharge() c.status = 'succeeded' c.paid = True return c monkeypatch.setattr("stripe.Charge.create", charge_create) prov = Stripe(event) req = factory.post( '/', { 'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu', 'stripe_last4': '4242', 'stripe_brand': 'Visa' }) req.session = {} prov.checkout_prepare(req, {}) assert 'payment_stripe_token' in req.session prov.payment_perform(req, order) order.refresh_from_db() assert order.status == Order.STATUS_PAID
def test_perform_failed(env, factory, monkeypatch): event, order = env def charge_create(**kwargs): c = MockedCharge() c.status = 'failed' c.paid = True c.failure_message = 'Foo' return c monkeypatch.setattr("stripe.Charge.create", charge_create) prov = Stripe(event) req = factory.post( '/', { 'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu', 'stripe_last4': '4242', 'stripe_brand': 'Visa' }) req.session = {} prov.checkout_prepare(req, {}) assert 'payment_stripe_token' in req.session with pytest.raises(PaymentException): prov.payment_perform(req, order) order.refresh_from_db() assert order.status == Order.STATUS_PENDING
def test_refund_unavailable(env, factory, monkeypatch): event, order = env def charge_retr(*args, **kwargs): def refund_create(): raise APIConnectionError(message='Foo') c = MockedCharge() c.refunds = object() c.refunds.create = refund_create() return c monkeypatch.setattr("stripe.Charge.retrieve", charge_retr) order.status = Order.STATUS_PAID order.payment_info = json.dumps({'id': 'ch_123345345'}) order.save() prov = Stripe(event) req = factory.get('/') req.user = None prov.order_control_refund_perform(req, order) order.refresh_from_db() assert order.status == Order.STATUS_PAID
def test_refund_success(env, factory, monkeypatch): event, order = env def charge_retr(*args, **kwargs): def refund_create(): pass c = MockedCharge() c.refunds = MockedCharge() c.refunds.create = refund_create return c monkeypatch.setattr("stripe.Charge.retrieve", charge_retr) order.status = Order.STATUS_PAID order.payment_info = json.dumps({'id': 'ch_123345345'}) order.save() prov = Stripe(event) req = factory.get('/') req.user = None prov.order_control_refund_perform(req, order) order.refresh_from_db() assert order.status == Order.STATUS_REFUNDED
def webhook(request): event_json = json.loads(request.body.decode("utf-8")) event_type = event_json["type"] if event_type != "charge.refunded": # Not interested return HttpResponse("Event is not a refund", status=200) charge = event_json["data"]["object"] if charge["object"] != "charge": return HttpResponse("Object is not a charge", status=200) metadata = charge["metadata"] if "event" not in metadata: return HttpResponse("Event not given", status=200) try: event = Event.objects.current.get(identity=metadata["event"]) except Event.DoesNotExist: return HttpResponse("Event not found", status=200) try: order = Order.objects.current.get(identity=metadata["order"]) except Order.DoesNotExist: return HttpResponse("Order not found", status=200) prov = Stripe(event) prov._init_api() try: charge = stripe.Charge.retrieve(charge["id"]) except stripe.error.StripeError as err: logger.error("Stripe error on webhook: %s Event data: %s" % (str(err), str(event_json))) return HttpResponse("StripeError", status=500) if charge["refunds"]["total_count"] > 0 and order.status == Order.STATUS_PAID: order.mark_refunded() return HttpResponse(status=200)
def test_perform_card_error(env, factory, monkeypatch): event, order = env def charge_create(**kwargs): raise CardError(message='Foo', param='foo', code=100) monkeypatch.setattr("stripe.Charge.create", charge_create) prov = Stripe(event) req = factory.post( '/', { 'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu', 'stripe_last4': '4242', 'stripe_brand': 'Visa' }) req.session = {} prov.checkout_prepare(req, {}) assert 'payment_stripe_token' in req.session prov.payment_perform(req, order) order.refresh_from_db() assert order.status == Order.STATUS_PENDING