Commit ec4a3f9d authored by Gabriel Monnerat's avatar Gabriel Monnerat

erp5_stripe: Use activity to store stripe session in ERP5

Creating Stripe Payment Session and HTTP Exchange in the same transaction can raise conflict errors and when it happens, we already created the session on the Stripe side.

With this, when this happens, we receive one useless webhook to inform that the session has expired.

Also, batch_mode was removed because we only use it in tests. The tests were updated to use like in production.
parent 5914be5a
...@@ -61,11 +61,9 @@ ...@@ -61,11 +61,9 @@
<value> <value>
<object> <object>
<klass> <klass>
<global name="_reconstructor" module="copy_reg"/> <global name="DateTime" module="DateTime.DateTime"/>
</klass> </klass>
<tuple> <tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/> <none/>
</tuple> </tuple>
<state> <state>
......
import json import json
portal = context.getPortalObject()
response = connector.createSession(data=data) response = connector.createSession(data=data)
assert "id" in response, response assert "id" in response, response
stripe_payment_session = portal.stripe_payment_session_module.newContent( context.activate().StripePaymentSessionModule_storeStripeSession(
portal_type="Stripe Payment Session",
reference=response["id"], reference=response["id"],
expiration_date=context.getTypeBasedMethod('getStripePaymentSessionExpirationDate')(), expiration_date=context.getTypeBasedMethod('getStripePaymentSessionExpirationDate')(),
resource=resource, resource=resource,
source_value=connector, source=connector.getRelativeUrl(),
causality=causality causality=causality,
)
http_exchange = portal.system_event_module.newContent(
portal_type="HTTP Exchange",
title="Create Session",
follow_up_value=stripe_payment_session,
source_value=context,
resource_value=portal.portal_categories.http_exchange_resource.stripe.create_session,
request=json.dumps(data, indent=2), request=json.dumps(data, indent=2),
response=json.dumps(response, indent=2) response=json.dumps(response, indent=2)
) )
http_exchange.confirm()
http_exchange.acknowledge()
stripe_payment_session.open()
if batch_mode:
return stripe_payment_session
return context.REQUEST.RESPONSE.redirect(response["url"]) return context.REQUEST.RESPONSE.redirect(response["url"])
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>connector, data, causality=None, resource=None, batch_mode=False</string> </value> <value> <string>connector, data, causality=None, resource=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
portal = context.getPortalObject()
stripe_payment_session = portal.stripe_payment_session_module.newContent(
portal_type="Stripe Payment Session",
reference=reference,
expiration_date=expiration_date,
resource=resource,
source_value=portal.restrictedTraverse(source),
causality=causality
)
http_exchange = portal.system_event_module.newContent(
portal_type="HTTP Exchange",
title="Create Session",
follow_up_value=stripe_payment_session,
resource_value=portal.portal_categories.http_exchange_resource.stripe.create_session,
)
http_exchange.confirm()
http_exchange.acknowledge()
stripe_payment_session.open()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>reference, expiration_date, resource, source, causality, request, response</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>StripePaymentSessionModule_storeStripeSession</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -205,7 +205,8 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -205,7 +205,8 @@ class TestStripePaymentSession(ERP5TypeTestCase):
return (200, {'content-type': 'application/json'}, json.dumps({ return (200, {'content-type': 'application/json'}, json.dumps({
"id": session_id, "id": session_id,
"status": status, "status": status,
"object": "checkout.session" "object": "checkout.session",
"url": "https://stripe.url"
})) }))
return _callback return _callback
...@@ -382,13 +383,16 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -382,13 +383,16 @@ class TestStripePaymentSession(ERP5TypeTestCase):
self.session_url, self.session_url,
self._response_callback("abc123") self._response_callback("abc123")
) )
stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( module.StripePaymentSessionModule_createStripeSession(
connector, connector,
self.data.copy(), self.data.copy(),
module.getRelativeUrl(), module.getRelativeUrl(),
batch_mode=True
) )
self.tic() self.tic()
stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference="abc123"
)
self.assertEqual(connector, stripe_payment_session.getSourceValue()) self.assertEqual(connector, stripe_payment_session.getSourceValue())
self._document_to_delete_list.append(stripe_payment_session) self._document_to_delete_list.append(stripe_payment_session)
self.assertEqual( self.assertEqual(
...@@ -415,8 +419,13 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -415,8 +419,13 @@ class TestStripePaymentSession(ERP5TypeTestCase):
self.session_url, self.session_url,
self._response_callback("abc321_expired") self._response_callback("abc321_expired")
) )
first_stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( module.StripePaymentSessionModule_createStripeSession(
connector, data, module.getRelativeUrl(), batch_mode=True) connector, data, module.getRelativeUrl())
self.tic()
first_stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference="abc321_expired"
)
first_stripe_payment_session.setExpirationDate(DateTime() - 1) first_stripe_payment_session.setExpirationDate(DateTime() - 1)
self.tic() self.tic()
...@@ -426,8 +435,13 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -426,8 +435,13 @@ class TestStripePaymentSession(ERP5TypeTestCase):
self.session_url, self.session_url,
self._response_callback("abc321_completed") self._response_callback("abc321_completed")
) )
second_stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( module.StripePaymentSessionModule_createStripeSession(
connector, data, module.getRelativeUrl(), batch_mode=True) connector, data, module.getRelativeUrl())
self.tic()
second_stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference="abc321_completed"
)
second_stripe_payment_session.setExpirationDate(DateTime() - 1) second_stripe_payment_session.setExpirationDate(DateTime() - 1)
self.tic() self.tic()
...@@ -449,6 +463,7 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -449,6 +463,7 @@ class TestStripePaymentSession(ERP5TypeTestCase):
"%s/ERP5Site_receiveStripeWebHook" % self.portal.getPath(), "%s/ERP5Site_receiveStripeWebHook" % self.portal.getPath(),
stdin=BytesIO(urllib.parse.urlencode({ stdin=BytesIO(urllib.parse.urlencode({
"BODY": json.dumps({ "BODY": json.dumps({
"url": "https://stripe.url",
"id": "evt_%s" % "abc321_expired", "id": "evt_%s" % "abc321_expired",
"object": "event", "object": "event",
"data": { "data": {
...@@ -490,7 +505,8 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -490,7 +505,8 @@ class TestStripePaymentSession(ERP5TypeTestCase):
json={ json={
"id": "test_update_expiration_date", "id": "test_update_expiration_date",
"status": "open", "status": "open",
"object": "checkout.session" "object": "checkout.session",
"url": "https://stripe.url"
}, },
) )
rsps.add( rsps.add(
...@@ -499,12 +515,17 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -499,12 +515,17 @@ class TestStripePaymentSession(ERP5TypeTestCase):
json={ json={
"id": "test_update_expiration_date", "id": "test_update_expiration_date",
"status": "open", "status": "open",
"object": "checkout.session" "object": "checkout.session",
}, },
) )
stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( module.StripePaymentSessionModule_createStripeSession(
connector, data, module.getRelativeUrl(), batch_mode=True) connector, data, module.getRelativeUrl())
self.tic()
stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference="test_update_expiration_date"
)
self.assertEqual("open", stripe_payment_session.getValidationState()) self.assertEqual("open", stripe_payment_session.getValidationState())
stripe_payment_session.setExpirationDate(DateTime() - 1) stripe_payment_session.setExpirationDate(DateTime() - 1)
self.tic() self.tic()
...@@ -531,10 +552,13 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -531,10 +552,13 @@ class TestStripePaymentSession(ERP5TypeTestCase):
stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( stripe_payment_session = module.StripePaymentSessionModule_createStripeSession(
connector, connector,
self.data.copy(), self.data.copy(),
module.getRelativeUrl(), module.getRelativeUrl()
batch_mode=True
) )
self.tic() self.tic()
stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference=session_id
)
self._document_to_delete_list.append(stripe_payment_session) self._document_to_delete_list.append(stripe_payment_session)
first_http_exchange, = stripe_payment_session.getFollowUpRelatedValueList( first_http_exchange, = stripe_payment_session.getFollowUpRelatedValueList(
...@@ -550,7 +574,7 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -550,7 +574,7 @@ class TestStripePaymentSession(ERP5TypeTestCase):
self.assertRaises( self.assertRaises(
requests.HTTPError, requests.HTTPError,
stripe_payment_session.StripePaymentSession_retrieveSession, stripe_payment_session.StripePaymentSession_retrieveSession,
connector, batch_mode=1 connector
) )
self.tic() self.tic()
...@@ -565,13 +589,15 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -565,13 +589,15 @@ class TestStripePaymentSession(ERP5TypeTestCase):
self.session_url, self.session_url,
self._response_callback(session_id) self._response_callback(session_id)
) )
stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( module.StripePaymentSessionModule_createStripeSession(
connector, connector,
self.data.copy(), self.data.copy(),
module.getRelativeUrl(), module.getRelativeUrl()
batch_mode=True
) )
self.tic() self.tic()
stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference=session_id)
self._document_to_delete_list.append(stripe_payment_session) self._document_to_delete_list.append(stripe_payment_session)
with responses.RequestsMock() as rsps: with responses.RequestsMock() as rsps:
...@@ -603,9 +629,11 @@ class TestStripePaymentSession(ERP5TypeTestCase): ...@@ -603,9 +629,11 @@ class TestStripePaymentSession(ERP5TypeTestCase):
stripe_payment_session = module.StripePaymentSessionModule_createStripeSession( stripe_payment_session = module.StripePaymentSessionModule_createStripeSession(
connector, connector,
self.data.copy(), self.data.copy(),
batch_mode=True
) )
self.tic() self.tic()
stripe_payment_session = self.portal.portal_catalog.getResultValue(
portal_type="Stripe Payment Session",
reference=session_id)
self._document_to_delete_list.append(stripe_payment_session) self._document_to_delete_list.append(stripe_payment_session)
first_http_exchange, = stripe_payment_session.getFollowUpRelatedValueList( first_http_exchange, = stripe_payment_session.getFollowUpRelatedValueList(
portal_type="HTTP Exchange") portal_type="HTTP Exchange")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment