@@ -506,48 +506,22 @@ def __init__(self, amount=None, currency=None, description=None,
506
506
self .status = 'pending'
507
507
self .receipt_email = None
508
508
self .receipt_number = None
509
+ self .payment_intent = None
509
510
self .payment_method = source .id
510
511
self .statement_descriptor = statement_descriptor
511
512
self .failure_code = None
512
513
self .failure_message = None
513
514
self .captured = capture
514
515
self .balance_transaction = None
515
516
516
- def _trigger_payment (self , on_success = None , on_failure_now = None ,
517
- on_failure_later = None ):
517
+ def _is_async_payment_method (self ):
518
518
pm = PaymentMethod ._api_retrieve (self .payment_method )
519
- async_payment = pm .type == 'sepa_debit'
519
+ return pm .type == 'sepa_debit'
520
520
521
- if async_payment :
522
- if not self ._authorized :
523
- async def callback ():
524
- await asyncio .sleep (0.5 )
525
- self .status = 'failed'
526
- if on_failure_later :
527
- on_failure_later ()
528
- else :
529
- async def callback ():
530
- await asyncio .sleep (0.5 )
531
- txn = BalanceTransaction (amount = self .amount ,
532
- currency = self .currency ,
533
- description = self .description ,
534
- exchange_rate = 1.0 ,
535
- reporting_category = 'charge' ,
536
- source = self .id , type = 'charge' )
537
- self .balance_transaction = txn .id
538
- self .status = 'succeeded'
539
- if on_success :
540
- on_success ()
541
- asyncio .ensure_future (callback ())
542
-
543
- else :
544
- if not self ._authorized :
545
- self .status = 'failed'
546
- self .failure_code = 'card_declined'
547
- self .failure_message = 'Your card was declined.'
548
- if on_failure_now :
549
- on_failure_now ()
550
- else :
521
+ def _trigger_payment (self , on_success = None ):
522
+ if self ._is_async_payment_method ():
523
+ async def callback ():
524
+ await asyncio .sleep (0.5 )
551
525
txn = BalanceTransaction (amount = self .amount ,
552
526
currency = self .currency ,
553
527
description = self .description ,
@@ -558,25 +532,58 @@ async def callback():
558
532
self .status = 'succeeded'
559
533
if on_success :
560
534
on_success ()
535
+ asyncio .ensure_future (callback ())
536
+
537
+ else :
538
+ txn = BalanceTransaction (amount = self .amount ,
539
+ currency = self .currency ,
540
+ description = self .description ,
541
+ exchange_rate = 1.0 ,
542
+ reporting_category = 'charge' ,
543
+ source = self .id , type = 'charge' )
544
+ self .balance_transaction = txn .id
545
+ self .status = 'succeeded'
546
+ if on_success :
547
+ on_success ()
561
548
562
549
@classmethod
563
550
def _api_create (cls , ** data ):
564
551
obj = super ()._api_create (** data )
565
552
566
- # for successful pre-auth, return unpaid charge
567
- if not obj .captured and obj ._authorized :
568
- return obj
553
+ obj ._initialize_charge (on_failure_now = obj ._raise_failure )
569
554
570
- def on_failure ():
571
- raise UserError (402 , 'Your card was declined.' ,
572
- {'code' : 'card_declined' , 'charge' : obj .id })
555
+ return obj
573
556
574
- obj . _trigger_payment (
575
- on_failure_now = on_failure ,
576
- on_failure_later = on_failure
577
- )
557
+ def _set_auth_failure ( self ):
558
+ self . status = 'failed'
559
+ self . failure_code = 'card_declined'
560
+ self . failure_message = 'Your card was declined.'
578
561
579
- return obj
562
+ def _raise_failure (self ):
563
+ raise UserError (402 , self .failure_message ,
564
+ {'code' : self .failure_code , 'charge' : self .id })
565
+
566
+ def _initialize_charge (self , on_success = None , on_failure_now = None ,
567
+ on_failure_later = None ):
568
+ if not self ._authorized :
569
+ if self ._is_async_payment_method ():
570
+ async def callback ():
571
+ await asyncio .sleep (0.5 )
572
+ self ._set_auth_failure ()
573
+ if on_failure_later :
574
+ on_failure_later ()
575
+ asyncio .ensure_future (callback ())
576
+ else :
577
+ self ._set_auth_failure ()
578
+ if on_failure_now :
579
+ on_failure_now ()
580
+
581
+ return
582
+
583
+ self .status = 'succeeded'
584
+
585
+ if self .captured :
586
+ self ._trigger_payment (on_success )
580
587
581
588
@classmethod
582
589
def _api_capture (cls , id , amount = None , ** kwargs ):
@@ -592,24 +599,26 @@ def _api_capture(cls, id, amount=None, **kwargs):
592
599
obj ._capture (amount )
593
600
return obj
594
601
595
- def _capture (self , amount ):
602
+ def _capture (self , amount , on_success = None ):
596
603
if amount is None :
597
604
amount = self .amount
598
605
599
606
amount = try_convert_to_int (amount )
600
607
try :
601
608
assert type (amount ) is int and 0 <= amount <= self .amount
602
- assert self .captured is False
609
+ assert self .captured is False and self . status == 'succeeded'
603
610
except AssertionError :
604
611
raise UserError (400 , 'Bad request' )
605
612
606
- def on_success ():
613
+ def on_success_capture ():
607
614
self .captured = True
608
615
if amount < self .amount :
609
616
refunded = self .amount - amount
610
617
Refund (charge = self .id , amount = refunded )
618
+ if on_success :
619
+ on_success ()
611
620
612
- self ._trigger_payment (on_success )
621
+ self ._trigger_payment (on_success = on_success_capture )
613
622
614
623
@property
615
624
def paid (self ):
@@ -1573,7 +1582,7 @@ def _api_pay_invoice(cls, id):
1573
1582
payment_method = pm .id )
1574
1583
obj .payment_intent = pi .id
1575
1584
pi .invoice = obj .id
1576
- PaymentIntent . _api_confirm ( obj . payment_intent )
1585
+ pi . _confirm ( on_failure_now = lambda : None )
1577
1586
1578
1587
return obj
1579
1588
@@ -1867,32 +1876,36 @@ def __init__(self, amount=None, currency=None, customer=None,
1867
1876
self ._canceled = False
1868
1877
self ._authentication_failed = False
1869
1878
1870
- def _trigger_payment (self ):
1871
- if self .status != 'requires_confirmation' :
1872
- raise UserError (400 , 'Bad request' )
1879
+ def _on_success (self ):
1880
+ if self .invoice :
1881
+ invoice = Invoice ._api_retrieve (self .invoice )
1882
+ invoice ._on_payment_success ()
1873
1883
1874
- def on_success ( ):
1875
- if self .invoice :
1876
- invoice = Invoice ._api_retrieve (self .invoice )
1877
- invoice ._on_payment_success ()
1884
+ def _report_failure ( self ):
1885
+ if self .invoice :
1886
+ invoice = Invoice ._api_retrieve (self .invoice )
1887
+ invoice ._on_payment_failure_now ()
1878
1888
1879
- def on_failure_now ():
1880
- if self .invoice :
1881
- invoice = Invoice ._api_retrieve (self .invoice )
1882
- invoice ._on_payment_failure_now ()
1889
+ self .latest_charge ._raise_failure ()
1883
1890
1884
- def on_failure_later ():
1885
- if self .invoice :
1886
- invoice = Invoice ._api_retrieve (self .invoice )
1887
- invoice ._on_payment_failure_later ()
1891
+ def _on_failure_later (self ):
1892
+ if self .invoice :
1893
+ invoice = Invoice ._api_retrieve (self .invoice )
1894
+ invoice ._on_payment_failure_later ()
1895
+
1896
+ def _create_charge (self , on_failure_now ):
1897
+ if self .status != 'requires_confirmation' :
1898
+ raise UserError (400 , 'Bad request' )
1888
1899
1889
1900
charge = Charge (amount = self .amount ,
1890
1901
currency = self .currency ,
1891
1902
customer = self .customer ,
1892
1903
source = self .payment_method ,
1893
1904
capture = (self .capture_method != "manual" ))
1905
+ charge .payment_intent = self .id
1894
1906
self .latest_charge = charge
1895
- charge ._trigger_payment (on_success , on_failure_now , on_failure_later )
1907
+ charge ._initialize_charge (self ._on_success , on_failure_now ,
1908
+ self ._on_failure_later )
1896
1909
1897
1910
@property
1898
1911
def status (self ):
@@ -1953,7 +1966,7 @@ def _api_create(cls, confirm=None, off_session=None, **data):
1953
1966
obj = super ()._api_create (** data )
1954
1967
1955
1968
if confirm :
1956
- cls . _api_confirm ( obj .id )
1969
+ obj . _confirm ( on_failure_now = obj ._report_failure )
1957
1970
1958
1971
return obj
1959
1972
@@ -1975,18 +1988,21 @@ def _api_confirm(cls, id, payment_method=None, **kwargs):
1975
1988
if obj .status != 'requires_confirmation' :
1976
1989
raise UserError (400 , 'Bad request' )
1977
1990
1978
- obj ._authentication_failed = False
1979
- payment_method = PaymentMethod ._api_retrieve (obj .payment_method )
1991
+ obj ._confirm (on_failure_now = obj ._report_failure )
1992
+
1993
+ return obj
1994
+
1995
+ def _confirm (self , on_failure_now ):
1996
+ self ._authentication_failed = False
1997
+ payment_method = PaymentMethod ._api_retrieve (self .payment_method )
1980
1998
if payment_method ._requires_authentication ():
1981
- obj .next_action = {
1999
+ self .next_action = {
1982
2000
'type' : 'use_stripe_sdk' ,
1983
2001
'use_stripe_sdk' : {'type' : 'three_d_secure_redirect' ,
1984
2002
'stripe_js' : '' },
1985
2003
}
1986
2004
else :
1987
- obj ._trigger_payment ()
1988
-
1989
- return obj
2005
+ self ._create_charge (on_failure_now = on_failure_now )
1990
2006
1991
2007
@classmethod
1992
2008
def _api_cancel (cls , id , ** kwargs ):
@@ -2030,7 +2046,7 @@ def _api_authenticate(cls, id, client_secret=None, success=False,
2030
2046
2031
2047
obj .next_action = None
2032
2048
if success :
2033
- obj ._trigger_payment ( )
2049
+ obj ._create_charge ( on_failure_now = obj . _report_failure )
2034
2050
else :
2035
2051
obj ._authentication_failed = True
2036
2052
obj .payment_method = None
@@ -2051,7 +2067,8 @@ def _api_capture(cls, id, amount_to_capture=None, **kwargs):
2051
2067
raise UserError (400 , 'Bad request' )
2052
2068
2053
2069
obj = cls ._api_retrieve (id )
2054
- obj .latest_charge ._capture (amount = amount_to_capture )
2070
+ obj .latest_charge ._capture (amount = amount_to_capture ,
2071
+ on_success = obj ._on_success )
2055
2072
return obj
2056
2073
2057
2074
0 commit comments