Files
tryton/modules/account_payment_stripe/tests/scenario_account_payment_stripe.rst
T

387 lines
10 KiB
ReStructuredText
Raw Normal View History

2017-04-01 19:14:28 +02:00
===============================
Account Payment Stripe Scenario
===============================
Imports::
>>> import datetime as dt
2024-01-14 19:21:56 +01:00
>>> import os
2020-04-01 23:53:38 +02:00
>>> import time
2017-04-01 19:14:28 +02:00
>>> from decimal import Decimal
2024-01-14 19:21:56 +01:00
2017-04-01 19:14:28 +02:00
>>> import stripe
2024-01-14 19:21:56 +01:00
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart, create_fiscalyear
>>> from trytond.modules.company.tests.tools import create_company, get_company
2017-04-01 19:14:28 +02:00
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
>>> FETCH_SLEEP, MAX_SLEEP = 1, 10
Activate modules::
2017-04-01 19:14:28 +02:00
>>> config = activate_modules('account_payment_stripe')
Create company::
>>> Company = Model.get('company.company')
>>> _ = create_company()
>>> company = get_company()
Create fiscal year::
>>> fiscalyear = create_fiscalyear(company, today)
2017-04-01 19:14:28 +02:00
>>> fiscalyear.click('create_period')
Create chart of accounts::
>>> _ = create_chart(company)
Create Stripe account::
>>> StripeAccount = Model.get('account.payment.stripe.account')
>>> stripe_account = StripeAccount(name="Stripe")
>>> stripe_account.secret_key = os.getenv('STRIPE_SECRET_KEY')
>>> stripe_account.publishable_key = os.getenv('STRIPE_PUBLISHABLE_KEY')
>>> stripe_account.save()
2019-10-10 18:45:36 +02:00
>>> stripe.api_key = os.getenv('STRIPE_SECRET_KEY')
2017-04-01 19:14:28 +02:00
2017-12-13 18:03:56 +01:00
Create webhook identifier::
>>> stripe_account.click('new_identifier')
>>> len(stripe_account.webhook_identifier)
32
2019-10-10 18:45:36 +02:00
Remove webhook::
>>> stripe_account.click('new_identifier')
>>> stripe_account.webhook_identifier
Setup fetch events cron::
>>> Cron = Model.get('ir.cron')
>>> cron_fetch_events, = Cron.find([
... ('method', '=', 'account.payment.stripe.account|fetch_events'),
... ])
>>> cron_fetch_events.companies.append(Company(company.id))
2017-04-01 19:14:28 +02:00
Create payment journal::
>>> PaymentJournal = Model.get('account.payment.journal')
>>> payment_journal = PaymentJournal(name="Stripe",
... process_method='stripe', stripe_account=stripe_account)
>>> payment_journal.save()
Create party::
>>> Party = Model.get('party.party')
>>> Lang = Model.get('ir.lang')
2017-04-01 19:14:28 +02:00
>>> customer = Party(name='Customer')
>>> customer.lang, = Lang.find([('code', '=', 'en')])
2017-04-01 19:14:28 +02:00
>>> customer.save()
2022-04-11 20:41:56 +02:00
Create submitted payment::
2017-04-01 19:14:28 +02:00
>>> Payment = Model.get('account.payment')
>>> payment = Payment()
>>> payment.journal = payment_journal
>>> payment.kind = 'receivable'
>>> payment.party = customer
>>> payment.amount = Decimal('42')
>>> payment.description = 'Testing'
2022-04-11 20:41:56 +02:00
>>> payment.click('submit')
2017-04-01 19:14:28 +02:00
>>> payment.state
2022-04-11 20:41:56 +02:00
'submitted'
2017-04-01 19:14:28 +02:00
Checkout the payment::
2023-01-17 14:39:18 +01:00
>>> checkout = payment.click('stripe_checkout')
2017-04-01 19:14:28 +02:00
>>> bool(payment.stripe_checkout_id)
True
>>> token = stripe.Token.create(
... card={
... 'number': '4242424242424242',
... 'exp_month': 12,
... 'exp_year': today.year + 1,
2017-04-01 19:14:28 +02:00
... 'cvc': '123',
... },
... )
2019-10-10 18:45:36 +02:00
>>> Payment.write([payment.id], {
... 'stripe_token': token.id,
... 'stripe_chargeable': True,
... 'stripe_payment_intent_id': None, # Remove intent from checkout
2019-10-10 18:45:36 +02:00
... }, config.context)
2017-04-01 19:14:28 +02:00
Process the payment::
>>> process_payment = payment.click('process_wizard')
2017-04-01 19:14:28 +02:00
>>> payment.state
2019-10-10 18:45:36 +02:00
'processing'
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... payment.reload()
... if payment.state == 'succeeded':
... break
... time.sleep(FETCH_SLEEP)
2019-10-10 18:45:36 +02:00
>>> payment.state
2018-06-26 19:11:43 +02:00
'succeeded'
2017-06-24 10:24:16 +02:00
>>> bool(payment.stripe_captured)
True
2017-04-01 19:14:28 +02:00
Create failing payment::
>>> previous_idempotency_key = payment.stripe_idempotency_key
2017-04-01 19:14:28 +02:00
>>> payment, = payment.duplicate()
>>> payment.stripe_idempotency_key != previous_idempotency_key
True
2022-04-11 20:41:56 +02:00
>>> payment.click('submit')
2017-04-01 19:14:28 +02:00
>>> payment.state
2022-04-11 20:41:56 +02:00
'submitted'
2023-01-17 14:39:18 +01:00
>>> checkout = payment.click('stripe_checkout')
2017-04-01 19:14:28 +02:00
>>> bool(payment.stripe_checkout_id)
True
>>> token = stripe.Token.create(
... card={
... 'number': '4000000000000002',
... 'exp_month': 12,
... 'exp_year': today.year + 1,
2017-04-01 19:14:28 +02:00
... 'cvc': '123',
... },
... )
2019-10-10 18:45:36 +02:00
>>> Payment.write([payment.id], {
... 'stripe_token': token.id,
2019-11-01 23:00:05 +01:00
... 'stripe_chargeable': True,
... 'stripe_payment_intent_id': None, # Remove intent from checkout
2019-10-10 18:45:36 +02:00
... }, config.context)
>>> process_payment = payment.click('process_wizard')
2017-04-01 19:14:28 +02:00
>>> payment.state
2018-06-26 19:11:43 +02:00
'failed'
2017-04-01 19:14:28 +02:00
>>> payment.stripe_error_code
2018-06-26 19:11:43 +02:00
'card_declined'
2017-04-01 19:14:28 +02:00
Create a customer::
>>> Customer = Model.get('account.payment.stripe.customer')
>>> stripe_customer = Customer()
>>> stripe_customer.party = customer
>>> stripe_customer.stripe_account = stripe_account
Checkout the customer::
2023-01-17 14:39:18 +01:00
>>> checkout = stripe_customer.click('stripe_checkout')
2017-04-01 19:14:28 +02:00
>>> bool(stripe_customer.stripe_checkout_id)
True
>>> token = stripe.Token.create(
... card={
... 'number': '4012888888881881',
... 'exp_month': 12,
... 'exp_year': today.year + 1,
2017-04-01 19:14:28 +02:00
... 'cvc': '123',
... },
... )
>>> Customer.write(
... [stripe_customer.id], {'stripe_token': token.id}, config.context)
2017-04-01 19:14:28 +02:00
Run cron::
>>> cron_customer_create, = Cron.find([
2019-04-12 16:48:49 +02:00
... ('method', '=', 'account.payment.stripe.customer|stripe_create'),
2017-04-01 19:14:28 +02:00
... ])
>>> cron_customer_create.companies.append(Company(company.id))
>>> cron_customer_create.click('run_once')
>>> stripe_customer.reload()
>>> bool(stripe_customer.stripe_customer_id)
True
Update customer::
>>> contact = customer.contact_mechanisms.new()
>>> contact.type = 'email'
>>> contact.value = 'customer@example.com'
>>> customer.save()
>>> cus = stripe.Customer.retrieve(stripe_customer.stripe_customer_id)
>>> cus.email
'customer@example.com'
>>> cus.preferred_locales
['en']
2017-04-01 19:14:28 +02:00
Make payment with customer::
>>> payment, = payment.duplicate()
2017-09-03 11:18:43 +02:00
>>> payment.stripe_customer = stripe_customer
>>> payment.save()
>>> _, source = Payment.get_stripe_customer_sources(payment.id, config.context)
>>> source_id, source_name = source
2023-12-28 23:00:52 +01:00
>>> source_name
'Visa ****1881 12/...'
2017-09-03 11:18:43 +02:00
>>> payment.stripe_customer_source = source_id
2022-04-11 20:41:56 +02:00
>>> payment.click('submit')
2017-04-01 19:14:28 +02:00
>>> payment.state
2022-04-11 20:41:56 +02:00
'submitted'
>>> process_payment = payment.click('process_wizard')
2017-04-01 19:14:28 +02:00
>>> payment.state
2019-10-10 18:45:36 +02:00
'processing'
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... payment.reload()
... if payment.state == 'succeeded':
... break
... time.sleep(FETCH_SLEEP)
2019-10-10 18:45:36 +02:00
>>> payment.state
2018-06-26 19:11:43 +02:00
'succeeded'
2017-04-01 19:14:28 +02:00
2020-08-11 21:47:51 +02:00
Detach source::
2023-01-17 14:39:18 +01:00
>>> detach = stripe_customer.click('detach_source')
2020-08-11 21:47:51 +02:00
>>> detach.form.source = source_id
>>> detach.execute('detach')
2022-09-25 20:26:21 +02:00
>>> cus = stripe.Customer.retrieve(
... stripe_customer.stripe_customer_id, expand=['sources'])
2020-08-11 21:47:51 +02:00
>>> len(cus.sources)
0
>>> len(stripe.PaymentMethod.list(customer=cus.id, type='card'))
0
2017-04-01 19:14:28 +02:00
Delete customer::
>>> stripe_customer.delete()
>>> bool(stripe_customer.active)
False
Run cron::
>>> cron_customer_delete, = Cron.find([
2019-04-12 16:48:49 +02:00
... ('method', '=', 'account.payment.stripe.customer|stripe_delete'),
2017-04-01 19:14:28 +02:00
... ])
>>> cron_customer_delete.companies.append(Company(company.id))
>>> cron_customer_delete.click('run_once')
>>> stripe_customer.reload()
>>> stripe_customer.stripe_token
>>> stripe_customer.stripe_customer_id
2017-06-24 10:24:16 +02:00
Create capture payment::
>>> payment, = payment.duplicate()
>>> payment.stripe_capture = False
2022-04-11 20:41:56 +02:00
>>> payment.click('submit')
2017-06-24 10:24:16 +02:00
>>> payment.state
2022-04-11 20:41:56 +02:00
'submitted'
2017-06-24 10:24:16 +02:00
Checkout the capture payment::
>>> token = stripe.Token.create(
... card={
... 'number': '4242424242424242',
... 'exp_month': 12,
... 'exp_year': today.year + 1,
2017-06-24 10:24:16 +02:00
... 'cvc': '123',
... },
... )
2019-10-10 18:45:36 +02:00
>>> Payment.write([payment.id], {
... 'stripe_token': token.id,
... }, config.context)
2017-06-24 10:24:16 +02:00
Process the capture payment::
>>> process_payment = payment.click('process_wizard')
2017-06-24 10:24:16 +02:00
>>> payment.state
2018-06-26 19:11:43 +02:00
'processing'
2017-06-24 10:24:16 +02:00
>>> bool(payment.stripe_captured)
False
Capture lower amount::
>>> payment.amount = Decimal('40')
2018-10-21 21:34:18 +02:00
>>> payment.click('stripe_do_capture')
2017-06-24 10:24:16 +02:00
>>> payment.state
2019-10-10 18:45:36 +02:00
'processing'
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... payment.reload()
... if payment.state == 'succeeded':
... break
... time.sleep(FETCH_SLEEP)
2019-10-10 18:45:36 +02:00
>>> payment.state
2018-06-26 19:11:43 +02:00
'succeeded'
2017-06-24 10:24:16 +02:00
>>> bool(payment.stripe_captured)
True
2018-01-12 13:09:11 +01:00
2020-04-11 00:22:48 +02:00
Refund some amount::
>>> Refund = Model.get('account.payment.stripe.refund')
>>> refund = Refund()
>>> refund.payment = payment
>>> refund.amount = Decimal('38')
2022-04-11 20:41:56 +02:00
>>> refund.click('submit')
2020-04-11 00:22:48 +02:00
>>> refund.click('approve')
>>> cron_refund_create, = Cron.find([
... ('method', '=', 'account.payment.stripe.refund|stripe_create'),
... ])
>>> cron_refund_create.click('run_once')
2018-01-12 13:09:11 +01:00
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... payment.reload()
... if payment.amount == Decimal('2.00'):
... break
... time.sleep(FETCH_SLEEP)
2018-01-12 13:09:11 +01:00
>>> payment.amount
Decimal('2.00')
>>> payment.state
2018-06-26 19:11:43 +02:00
'succeeded'
2020-04-11 00:22:48 +02:00
>>> refund.reload()
>>> refund.state
'succeeded'
2018-01-12 13:09:11 +01:00
Simulate charge.refunded event with full amount::
2020-04-11 00:22:48 +02:00
>>> refund = Refund()
>>> refund.payment = payment
>>> refund.amount = Decimal('2')
2022-04-11 20:41:56 +02:00
>>> refund.click('submit')
2020-04-11 00:22:48 +02:00
>>> refund.click('approve')
>>> cron_refund_create.click('run_once')
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... payment.reload()
... if payment.amount == Decimal('0.00'):
... break
... time.sleep(FETCH_SLEEP)
2018-01-12 13:09:11 +01:00
>>> payment.amount
Decimal('0.00')
>>> payment.state
2018-06-26 19:11:43 +02:00
'failed'
2020-04-11 00:22:48 +02:00
>>> refund.reload()
>>> refund.state
'succeeded'
Try to refund more::
>>> refund = Refund()
>>> refund.payment = payment
>>> refund.amount = Decimal('10')
2022-04-11 20:41:56 +02:00
>>> refund.click('submit')
2020-04-11 00:22:48 +02:00
>>> refund.click('approve')
>>> cron_refund_create.click('run_once')
>>> for _ in range(MAX_SLEEP):
... cron_fetch_events.click('run_once')
... refund.reload()
... if refund.state == 'failed':
... break
... time.sleep(FETCH_SLEEP)
2020-04-11 00:22:48 +02:00
>>> refund.state
'failed'