@@ -347,47 +347,62 @@ export class CheckoutService {
347347 subscription . latest_invoice
348348 ) ;
349349
350- assert (
351- invoice . payment_intent ,
352- 'payment_intent does not exist on subscription'
353- ) ;
354- // Confirm intent with collected payment method
355- const paymentIntent = await this . paymentIntentManager . confirm (
356- invoice . payment_intent ,
357- {
358- confirmation_token : confirmationTokenId ,
359- off_session : false ,
360- }
361- ) ;
350+ if ( invoice . amount_due === 0 ) {
351+ // invoices without charge do not generate a payent intent
352+ assert (
353+ invoice . status === 'paid' ,
354+ 'Zero-charge stripe invoice expected to be in a paid status'
355+ ) ;
356+ const paymentMethod = await this . customerManager . getDefaultPaymentMethod (
357+ customer . id
358+ ) ;
359+ assert (
360+ ! ! paymentMethod ,
361+ 'Payment method expected on customer for stripe zero-charge payment processing'
362+ ) ;
363+ } else {
364+ assert (
365+ invoice . payment_intent ,
366+ 'payment_intent does not exist on subscription'
367+ ) ;
368+ // Confirm intent with collected payment method
369+ const paymentIntent = await this . paymentIntentManager . confirm (
370+ invoice . payment_intent ,
371+ {
372+ confirmation_token : confirmationTokenId ,
373+ off_session : false ,
374+ }
375+ ) ;
362376
363- if ( paymentIntent . status === 'requires_action' ) {
364- await this . cartManager . setNeedsInputCart ( cart . id ) ;
365- return ;
366- } else if ( paymentIntent . status === 'succeeded' ) {
367- if ( paymentIntent . payment_method ) {
368- await this . customerManager . update ( customer . id , {
369- invoice_settings : {
370- default_payment_method : paymentIntent . payment_method ,
371- } ,
372- } ) ;
377+ if ( paymentIntent . status === 'requires_action' ) {
378+ await this . cartManager . setNeedsInputCart ( cart . id ) ;
379+ return ;
380+ } else if ( paymentIntent . status === 'succeeded' ) {
381+ if ( paymentIntent . payment_method ) {
382+ await this . customerManager . update ( customer . id , {
383+ invoice_settings : {
384+ default_payment_method : paymentIntent . payment_method ,
385+ } ,
386+ } ) ;
387+ } else {
388+ throw new CartError (
389+ 'Failed to update customer default payment method' ,
390+ { cartId : cart . id }
391+ ) ;
392+ }
373393 } else {
374- throw new CartError (
375- 'Failed to update customer default payment method' ,
376- { cartId : cart . id }
394+ throw new CheckoutPaymentError (
395+ `Expected payment intent status to be one of [requires_action, succeeded], instead found: ${ paymentIntent . status } `
377396 ) ;
378397 }
379- await this . postPaySteps ( {
380- cart,
381- version : updatedVersion ,
382- subscription,
383- uid,
384- paymentProvider : 'stripe' ,
385- } ) ;
386- } else {
387- throw new CheckoutPaymentError (
388- `Expected payment intent status to be one of [requires_action, succeeded], instead found: ${ paymentIntent . status } `
389- ) ;
390398 }
399+ await this . postPaySteps ( {
400+ cart,
401+ version : updatedVersion ,
402+ subscription,
403+ uid,
404+ paymentProvider : 'stripe' ,
405+ } ) ;
391406 }
392407
393408 async payWithPaypal (
0 commit comments