I'm using webforms and VB. I am calling Stripe to perform an ACH transaction. I have a standalone program that works, however when I put the code in my production application, the flow is not what I'm expecting.
I'm reading a gridview which contains customer IDs of records which need to be billed via Stripe. I have a button (btnPost) which starts the process. That button calls an Async Sub which loops through the gridview. For each row I call a "Post_ACHAsync" subroutine, which is also Async. Within the "Post_ACHAsync" subroutine is the call to Stripe, with an "Await", which returns a Task.
The problem is that, when the call to Stripe is done, it goes back to the For/Each loop instead of proceeding with code. Why is it doing that?
Here's the code:
Protected Sub btnPost_Click(sender As Object, e As EventArgs) Handles btnPost.Click
PostTransactions()
PopulatePendingTrxs()
End Sub
Protected Async Sub PostTransactions()
For Each row As GridViewRow In gvTrxs.Rows
Select Case row.Cells(2).Text.ToUpper()
Case "B"
'--- Bank Account (ACH)
Post_ACHAsync([parameters])
Case "C"
'--- Credit Card
Post_CC(row)
Case Else
End Select
Next
End Sub
Private Async Sub Post_ACHAsync([parameters])
dim oM as new BillingMaster()
'--- call Stripe
Try
Dim stripeService As New StripeService()
Dim chargeId As String = Await stripeService.ProcessAchTransferAsync([parameters])
' Success!
oM.Status = "W" 'Withdrawal
oM.SuccessOrFailure = "S"
oM.StripeWithdrawalID = chargeId
oM.StripeWithdrawalMsg = "Success"
colErrors = oM.SaveRecord(oM)
Catch ex As Exception
OKtoContinue = False
colErrors.Add(ex.Message)
End Try
If Not OKtoContinue Then
oM.PostGUID = strPostGUID
oM.Status = "F"
oM.SuccessOrFailure = "F"
oM.StripeWithdrawalID = ""
oM.WithdrawalDate = DateTime.Now
oM.StripeWithdrawalMsg = SplitErrors(colErrors)
colErrors = oM.SaveRecord(oM)
End If
oM = Nothing
End Sub
Public Async Function ProcessAchTransferAsync([parameters]) As Task(Of String)
Try
'--- do Stripe stuff here
Return charge.Id
Catch ex As StripeException
' Log the error
System.Diagnostics.Debug.WriteLine($"Stripe Error: {If(ex.StripeError?.Message, ex.Message)}")
Throw New Exception($"Payment processing error: {If(ex.StripeError?.Message, ex.Message)}")
Catch ex As Exception
' Log the error
System.Diagnostics.Debug.WriteLine($"General Error: {ex.Message}")
Throw New Exception("An unexpected error occurred while processing your payment. Please try again.")
End Try
End Function
After the Await stripeService.ProcessAchTransferAsync
line, the flow goes back to the For/Each loop; it doesn't continue with the "Success" (or Catch) code.
Do I need both subroutines to be Async? Should there be another "Await" somewhere?