Stripe - payments platform
Summary of challenges encountered during big integration of Stripe with e-commerce service
Krzysztof "noisy" Szumny
PSD2 and New Regulations
PSD2 and New Regulations
In a typical marketplace setup, where a platform acts as an intermediary for both buyers and sellers without itself selling the product or service, the platform can no longer receive payments that are owed by buyers to sellers. If it does, it will have to obtain a payments license from a regulator and become a regulated business.
Strong Customer Authentication (SCA)
Strong Customer Authentication (SCA)
Migration
Stripe
Charge API
Stripe
Payment Intents API
Demo
Chalanges
Challenge #1: Understanding the scope
Charges/PI API
Stripe Connect
Stripe JS & Python Libraries
implementation
&
configuration
Many different products
Mixed interface for multiple features
stripe.PaymentIntent.create(
confirm=True,
amount=self.amount,
currency=self.currency,
description="full payment (%s)" % self.order.id,
statement_descriptor=self.statement_descriptor,
idempotency_key="charge-%s" % self.order.id,
confirmation_method='automatic',
setup_future_usage='off_session',
return_url=url,
payment_method_options=payment_method_options,
stripe_account=stripe_user_id,
payment_method=shared_payment_method_id,
application_fee_amount=self.application_fee,
)
Stripe Connect Related params
needed so function would behave like stripe.PaymentIntent.confirm
customizing the 3D Secure UI
- https://stripe.com/docs/connect/charges
- https://stripe.com/docs/payments/3d-secure/web#custom-iframe
- https://stripe.com/docs/payments/cards/saving-cards-after-payment
- https://stripe.com/docs/payments/payment-intents/use-cases#one-time-payments
- https://stripe.com/docs/api/idempotent_requests
- https://stripe.com/docs/api/payment_intents/create#create_payment_intent-confirm
"saving card" related param
webhook related param
consistency related param
API Documentation, brief description of all params:
Challenge #2: Replacing payment API without a downtime
Stripe
Charge API
Stripe
Payment Intents API
Solution: Feature flipper
Challenge #3: Multiple workflows
Pitchup.com direct payment
- User makes a booking on Pitchup
- Pitchup.com charges user a reservation fee
- User pays a campsite when he arrives (by cash, credit card, etc)
Deferred payment
- User makes a booking on Pitchup, in advance (for example 2 months earlier)
- Pitchup.com charges user a reservation fee
- X days before an arrival, payment for campsite is initiated by Pitchup
Immediate combined payment
- User makes a booking on Pitchup (for example 5 days before an arrival)
- Pitchup charges user a full amount immediately (reservation fee + payment for campsite)
Different payment methods
+ "saved" cards
A lot of different testing scenarios
Solution: Integration tests
charge_api/test_pitchup_payment.py::TestStripePitchupPaymentChargesAPI::test_stripe_pitchup_payment_with_stored_card PASSED [ 3%]
charge_api/test_pitchup_payment.py::TestStripePitchupPaymentChargesAPI::test_stripe_pitchup_payment_without_store PASSED [ 6%]
charge_api/test_pitchup_payment.py::TestStripePitchupPaymentChargesAPI::test_stripe_pitchup_payment_with_store PASSED [ 10%]
intents_api/test_immediate.py::test_stripe_immediate_payment_by_anonymous_user PASSED [ 13%]
intents_api/test_immediate.py::test_stripe_immediate_payment_with_store PASSED [ 16%]
intents_api/test_immediate.py::test_stripe_immediate_payment_with_stored_charges_api_card PASSED [ 20%]
intents_api/test_immediate.py::test_stripe_immediate_payment_without_store PASSED [ 23%]
intents_api/test_immediate.py::test_stripe_immediate_payment_with_stored_card PASSED [ 26%]
test_handler_base.py::TestStoreCardBase::test_get_payment_method_id PASSED [ 30%]
test_handler_base.py::TestStoreCardBase::test_get_stripe_token PASSED [ 33%]
intents_api/test_deferred.py::test_stripe_deferred_payment_without_store PASSED [ 36%]
intents_api/test_deferred.py::test_stripe_deferred_payment_by_anonymous_user PASSED [ 40%]
intents_api/test_deferred.py::test_stripe_deferred_payment_with_legacy_1st_payment PASSED [ 43%]
intents_api/test_deferred.py::test_stripe_deferred_payment_with_stored_card PASSED [ 46%]
intents_api/test_deferred.py::test_stripe_deferred_payment_with_store PASSED [ 50%]
charge_api/test_future_payment.py::test_stripe_future_payment_uses_correct_card PASSED [ 53%]
charge_api/test_future_payment.py::test_stripe_future_payment_no_user_stored_card PASSED [ 56%]
charge_api/test_future_payment.py::test_stripe_future_payment2_without_stored_card PASSED [ 60%]
charge_api/test_future_payment.py::test_stripe_future_payment_with_store PASSED [ 63%]
charge_api/test_future_payment.py::test_stripe_future_payment_to_correct_card PASSED [ 66%]
charge_api/test_future_payment.py::test_stripe_future_payment_without_store PASSED [ 70%]
charge_api/test_future_payment.py::test_stripe_future_payment_idempotent PASSED [ 73%]
charge_api/test_future_payment.py::test_stripe_future_payment_with_stored_card PASSED [ 76%]
intents_api/test_pitchup.py::test_stripe_pitchup_payment_with_store PASSED [ 80%]
intents_api/test_pitchup.py::test_stripe_pitchup_payment_with_stored_card PASSED [ 83%]
intents_api/test_pitchup.py::test_stripe_pitchup_payment_without_store PASSED [ 86%]
intents_api/test_pitchup.py::test_stripe_pitchup_payment_by_anonymous_user PASSED [ 90%]
charge_api/test_immediate_payment.py::test_stripe_immediate_payment_with_store PASSED [ 93%]
charge_api/test_immediate_payment.py::test_stripe_immediate_payment_with_stored_card PASSED [ 96%]
charge_api/test_immediate_payment.py::test_stripe_immediate_payment_without_store PASSED [100%]
================================================== 30 passed in 185.33 seconds =====================================================
Challenge #4: Multiple implementations
Pitchup.com direct payment
- User makes a booking on Pitchup
- Pitchup.com charges user a reservation fee
- User pays a campsite when he arrives (by cash, credit card, etc)
Deferred payment
- User makes a booking on Pitchup, in advance (for example 2 months earlier)
- Pitchup.com charges user a reservation fee
- X days before an arrival, payment for campsite is initiated by Pitchup
Immediate combined payment
- User makes a booking on Pitchup (for example 5 days before an arrival)
- Pitchup charges user a full amount immediately (reservation fee + payment for campsite)
Direct Payment
Implementation
Immediate Payment
Implementation
Deferred Payment
Implementation
Challenge #4: Multiple implementations
Pitchup.com direct payment
- User makes a booking on Pitchup
- Pitchup.com charges user a reservation fee
- User pays a campsite when he arrives (by cash, credit card, etc)
Deferred payment
- User makes a booking on Pitchup, in advance (for example 2 months earlier)
- Pitchup.com charges user a reservation fee
- X days before an arrival, payment for campsite is initiated by Pitchup
Immediate combined payment
- User makes a booking on Pitchup (for example 5 days before an arrival)
- Pitchup charges user a full amount immediately (reservation fee + payment for campsite)
Common interface
PaymentTypeAHandler
BasePaymentHandler
PaymentTypeBHandler
PaymentTypeCHandler
Challenge #5: Too simple examples in Stripe documentation
- How to make a simple transaction via Stripe Payment Intent API
- How to "save a card", so use could reuse it in the future
- How to handle 3D Secure Authorization
- How to handle Stripe Webhook events
Frontend
Backend
3D Secure
Pop up
Stripe
Payment Intent creation
Actual Payment
Stripe JS Library
Stripe Python Library
Frontend
Backend
3D Secure
Pop up
Stripe
Payment Intent creation
Actual Payment
Stripe JS Library
Stripe Python Library
Suggestion: Pair programming
Challenge #6: Setup of Stripe Connect
Your Stripe Account
Connected accounts
Webhook
Webhook connect
Be careful to not connect your account to itself
Challenge #7: Webhook events
Your Stripe Account
Connected accounts
Webhook
Webhook connect
stripe listen \
--events payment_intent.succedded,payment_intent.payment_failed \
--forward-to localhost:9000/events
> Ready! Your webhook signing secret is whsec_2RoT8DNVbh6mVWKULRGvo64a304PjOaw (^C to quit)
Time consuming setup of webhook listener for local development
Two types of webhook endpoints
Your Stripe Account
Connected accounts
Webhook
Webhook connect
Events from connected account, from other platforms
Another Stripe Account
- Format of webhook events is not always consistent
- different structure, for events originated by actions from different API
Challenge #8: Multiple environments
Your Stripe Account
Connected accounts
Webhook
Webhook connect
Your Stripe Account
Connected accounts
Your Stripe Account
Connected accounts
Suggestion: Setup new dedicated account(s)
Do I recommend Stripe?
Q&A
Stripe - payments platform
By noisy
Stripe - payments platform
- 1,163