forked from CGM_Public/pretix_original
Stripe SCA (#1275)
* Stripe SCA - Upgrade to latest Stripe API - Deprecate Stripe Checkout for CC - Migrate CC payments to Payment Intents * Move SCA to its own view * Handle CardErrors for PaymentIntents * Abilty to handle charge webhooks with PaymentIntents * Better handling of Stripe References * Fix Stripe Tests * Move SCA page into orderlayout; perform iFrame SCA * Handle disputes and pi-webhooks better, fill more into ReferencedStripeObject * Optionally pass prefetched PaymentIntent to handle-func * Fix style * Send message to window.parent not window.top (widget compatibility) * More accurate loading message * Show a cog on sca_return.html. On a good internet connection, you barely see it, but on a bad one… * Robust error handling * If it's a method and used like a method, let's actually call it like a method! * Remove logging statement * Fix JavaScript interference with other frame events * Use 4:3 aspect ratio, but at least 600px * Adjust to django_scopes
This commit is contained in:
committed by
Raphael Michel
parent
b727207e79
commit
446cf68377
@@ -10,15 +10,26 @@ from pretix.testutils.sessions import add_cart_session, get_cart_session_key
|
||||
|
||||
|
||||
class MockedCharge():
|
||||
def __init__(self):
|
||||
self.status = ''
|
||||
self.paid = False
|
||||
self.id = 'ch_123345345'
|
||||
status = ''
|
||||
paid = False
|
||||
id = 'ch_123345345'
|
||||
|
||||
def refresh(self):
|
||||
pass
|
||||
|
||||
|
||||
class Object():
|
||||
pass
|
||||
|
||||
|
||||
class MockedPaymentintent():
|
||||
status = ''
|
||||
id = 'pi_1EUon12Tb35ankTnZyvC3SdE'
|
||||
charges = Object()
|
||||
charges.data = [MockedCharge()]
|
||||
last_payment_error = None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def env(client):
|
||||
orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
@@ -41,16 +52,17 @@ def env(client):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_payment(env, monkeypatch):
|
||||
def charge_create(**kwargs):
|
||||
def paymentintent_create(**kwargs):
|
||||
assert kwargs['amount'] == 1337
|
||||
assert kwargs['currency'] == 'eur'
|
||||
assert kwargs['source'] == 'tok_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedCharge()
|
||||
assert kwargs['payment_method'] == 'pm_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedPaymentintent()
|
||||
c.status = 'succeeded'
|
||||
c.paid = True
|
||||
charge_create.called = True
|
||||
c.charges.data[0].paid = True
|
||||
setattr(paymentintent_create, 'called', True)
|
||||
return c
|
||||
monkeypatch.setattr("stripe.Charge.create", charge_create)
|
||||
|
||||
monkeypatch.setattr("stripe.PaymentIntent.create", paymentintent_create)
|
||||
|
||||
client, ticket = env
|
||||
session_key = get_cart_session_key(client, ticket.event)
|
||||
@@ -62,17 +74,16 @@ def test_payment(env, monkeypatch):
|
||||
client.post('/%s/%s/checkout/questions/' % (ticket.event.organizer.slug, ticket.event.slug), {
|
||||
'email': 'admin@localhost'
|
||||
}, follow=True)
|
||||
charge_create.called = False
|
||||
paymentintent_create.called = False
|
||||
response = client.post('/%s/%s/checkout/payment/' % (ticket.event.organizer.slug, ticket.event.slug), {
|
||||
'payment': 'stripe',
|
||||
'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'payment_method': 'pm_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'stripe_card_brand': 'visa',
|
||||
'stripe_card_last4': '1234'
|
||||
}, follow=True)
|
||||
assert not charge_create.called
|
||||
assert not paymentintent_create.called
|
||||
assert response.status_code == 200
|
||||
assert 'alert-danger' not in response.rendered_content
|
||||
response = client.post('/%s/%s/checkout/confirm/' % (ticket.event.organizer.slug, ticket.event.slug), {
|
||||
}, follow=True)
|
||||
assert charge_create.called
|
||||
assert response.status_code == 200
|
||||
|
||||
@@ -46,39 +46,51 @@ class MockedRefunds():
|
||||
|
||||
|
||||
class MockedCharge():
|
||||
def __init__(self):
|
||||
self.status = ''
|
||||
self.paid = False
|
||||
self.id = 'ch_123345345'
|
||||
self.refunds = MockedRefunds()
|
||||
status = ''
|
||||
paid = False
|
||||
id = 'ch_123345345'
|
||||
refunds = MockedRefunds()
|
||||
|
||||
def refresh(self):
|
||||
pass
|
||||
|
||||
|
||||
class Object():
|
||||
pass
|
||||
|
||||
|
||||
class MockedPaymentintent():
|
||||
status = ''
|
||||
id = 'pi_1EUon12Tb35ankTnZyvC3SdE'
|
||||
charges = Object()
|
||||
charges.data = [MockedCharge()]
|
||||
last_payment_error = None
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_perform_success(env, factory, monkeypatch):
|
||||
event, order = env
|
||||
|
||||
def charge_create(**kwargs):
|
||||
def paymentintent_create(**kwargs):
|
||||
assert kwargs['amount'] == 1337
|
||||
assert kwargs['currency'] == 'eur'
|
||||
assert kwargs['source'] == 'tok_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedCharge()
|
||||
assert kwargs['payment_method'] == 'pm_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedPaymentintent()
|
||||
c.status = 'succeeded'
|
||||
c.paid = True
|
||||
c.charges.data[0].paid = True
|
||||
return c
|
||||
|
||||
monkeypatch.setattr("stripe.Charge.create", charge_create)
|
||||
monkeypatch.setattr("stripe.PaymentIntent.create", paymentintent_create)
|
||||
|
||||
prov = StripeCC(event)
|
||||
req = factory.post('/', {
|
||||
'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'stripe_payment_method_id': 'pm_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'stripe_last4': '4242',
|
||||
'stripe_brand': 'Visa'
|
||||
})
|
||||
req.session = {}
|
||||
prov.checkout_prepare(req, {})
|
||||
assert 'payment_stripe_token' in req.session
|
||||
assert 'payment_stripe_payment_method_id' in req.session
|
||||
payment = order.payments.create(
|
||||
provider='stripe_cc', amount=order.total
|
||||
)
|
||||
@@ -93,25 +105,25 @@ def test_perform_success_zero_decimal_currency(env, factory, monkeypatch):
|
||||
event.currency = 'JPY'
|
||||
event.save()
|
||||
|
||||
def charge_create(**kwargs):
|
||||
def paymentintent_create(**kwargs):
|
||||
assert kwargs['amount'] == 13
|
||||
assert kwargs['currency'] == 'jpy'
|
||||
assert kwargs['source'] == 'tok_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedCharge()
|
||||
assert kwargs['payment_method'] == 'pm_189fTT2eZvKYlo2CvJKzEzeu'
|
||||
c = MockedPaymentintent()
|
||||
c.status = 'succeeded'
|
||||
c.paid = True
|
||||
c.charges.data[0].paid = True
|
||||
return c
|
||||
|
||||
monkeypatch.setattr("stripe.Charge.create", charge_create)
|
||||
monkeypatch.setattr("stripe.PaymentIntent.create", paymentintent_create)
|
||||
prov = StripeCC(event)
|
||||
req = factory.post('/', {
|
||||
'stripe_token': 'tok_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'stripe_payment_method_id': 'pm_189fTT2eZvKYlo2CvJKzEzeu',
|
||||
'stripe_last4': '4242',
|
||||
'stripe_brand': 'Visa'
|
||||
})
|
||||
req.session = {}
|
||||
prov.checkout_prepare(req, {})
|
||||
assert 'payment_stripe_token' in req.session
|
||||
assert 'payment_stripe_payment_method_id' in req.session
|
||||
payment = order.payments.create(
|
||||
provider='stripe_cc', amount=order.total
|
||||
)
|
||||
@@ -136,7 +148,7 @@ def test_perform_card_error(env, factory, monkeypatch):
|
||||
})
|
||||
req.session = {}
|
||||
prov.checkout_prepare(req, {})
|
||||
assert 'payment_stripe_token' in req.session
|
||||
assert 'payment_stripe_payment_method_id' in req.session
|
||||
with pytest.raises(PaymentException):
|
||||
payment = order.payments.create(
|
||||
provider='stripe_cc', amount=order.total
|
||||
@@ -162,7 +174,7 @@ def test_perform_stripe_error(env, factory, monkeypatch):
|
||||
})
|
||||
req.session = {}
|
||||
prov.checkout_prepare(req, {})
|
||||
assert 'payment_stripe_token' in req.session
|
||||
assert 'payment_stripe_payment_method_id' in req.session
|
||||
with pytest.raises(PaymentException):
|
||||
payment = order.payments.create(
|
||||
provider='stripe_cc', amount=order.total
|
||||
@@ -192,7 +204,7 @@ def test_perform_failed(env, factory, monkeypatch):
|
||||
})
|
||||
req.session = {}
|
||||
prov.checkout_prepare(req, {})
|
||||
assert 'payment_stripe_token' in req.session
|
||||
assert 'payment_stripe_payment_method_id' in req.session
|
||||
with pytest.raises(PaymentException):
|
||||
payment = order.payments.create(
|
||||
provider='stripe_cc', amount=order.total
|
||||
|
||||
Reference in New Issue
Block a user