@@ -124,7 +124,7 @@ public bool IsSponsoredSubscription(Subscription subscription) =>
124124 /// <param name="userId"></param>
125125 /// /// <param name="providerId"></param>
126126 /// <returns></returns>
127- public Transaction FromChargeToTransaction ( Charge charge , Guid ? organizationId , Guid ? userId , Guid ? providerId )
127+ public async Task < Transaction > FromChargeToTransactionAsync ( Charge charge , Guid ? organizationId , Guid ? userId , Guid ? providerId )
128128 {
129129 var transaction = new Transaction
130130 {
@@ -209,6 +209,24 @@ public Transaction FromChargeToTransaction(Charge charge, Guid? organizationId,
209209 transaction . PaymentMethodType = PaymentMethodType . BankAccount ;
210210 transaction . Details = $ "ACH => { achCreditTransfer . BankName } , { achCreditTransfer . AccountNumber } ";
211211 }
212+ else if ( charge . PaymentMethodDetails . CustomerBalance != null )
213+ {
214+ var bankTransferType = await GetFundingBankTransferTypeAsync ( charge ) ;
215+
216+ if ( ! string . IsNullOrEmpty ( bankTransferType ) )
217+ {
218+ transaction . PaymentMethodType = PaymentMethodType . BankAccount ;
219+ transaction . Details = bankTransferType switch
220+ {
221+ "eu_bank_transfer" => "EU Bank Transfer" ,
222+ "gb_bank_transfer" => "GB Bank Transfer" ,
223+ "jp_bank_transfer" => "JP Bank Transfer" ,
224+ "mx_bank_transfer" => "MX Bank Transfer" ,
225+ "us_bank_transfer" => "US Bank Transfer" ,
226+ _ => "Bank Transfer"
227+ } ;
228+ }
229+ }
212230
213231 break ;
214232 }
@@ -406,4 +424,55 @@ private async Task<bool> AttemptToPayInvoiceWithStripeAsync(Invoice invoice)
406424 throw ;
407425 }
408426 }
427+
428+ /// <summary>
429+ /// Retrieves the bank transfer type that funded a charge paid via customer balance.
430+ /// </summary>
431+ /// <param name="charge">The charge to analyze.</param>
432+ /// <returns>
433+ /// The bank transfer type (e.g., "us_bank_transfer", "eu_bank_transfer") if the charge was funded
434+ /// by a bank transfer via customer balance, otherwise null.
435+ /// </returns>
436+ private async Task < string > GetFundingBankTransferTypeAsync ( Charge charge )
437+ {
438+ if ( charge is not
439+ {
440+ CustomerId : not null ,
441+ PaymentIntentId : not null ,
442+ PaymentMethodDetails : { Type : "customer_balance" }
443+ } )
444+ {
445+ return null ;
446+ }
447+
448+ var cashBalanceTransactions = _stripeFacade . GetCustomerCashBalanceTransactions ( charge . CustomerId ) ;
449+
450+ string bankTransferType = null ;
451+ var matchingPaymentIntentFound = false ;
452+
453+ await foreach ( var cashBalanceTransaction in cashBalanceTransactions )
454+ {
455+ switch ( cashBalanceTransaction )
456+ {
457+ case { Type : "funded" , Funded : not null } :
458+ {
459+ bankTransferType = cashBalanceTransaction . Funded . BankTransfer . Type ;
460+ break ;
461+ }
462+ case { Type : "applied_to_payment" , AppliedToPayment : not null }
463+ when cashBalanceTransaction . AppliedToPayment . PaymentIntentId == charge . PaymentIntentId :
464+ {
465+ matchingPaymentIntentFound = true ;
466+ break ;
467+ }
468+ }
469+
470+ if ( matchingPaymentIntentFound && ! string . IsNullOrEmpty ( bankTransferType ) )
471+ {
472+ return bankTransferType ;
473+ }
474+ }
475+
476+ return null ;
477+ }
409478}
0 commit comments