Well this is going to be a mixed answer.
The SQL you have is correct for doing an UPDATE, and is not susceptible to SQL Injection.
What is most likely incorrect is data-types; subtraction infers that the data should be numerical in nature- but you are passing in
@wallet as text.
UPDATE: based on comments that have come in... you need to correct the data types in your database
What is also incorrect is the sequence of events; you are doing the UPDATE before you check to see if there is sufficient funds.
What we don't know is what the values are or represent, so there may be other issues.
It also looks like you may not be calculating values correctly.
Here is some pseudo-VB on what I would expect to see for something like this. You may need to change data types for things such as currency amount.
Dim FundsNeeded as Int = Val(TextBoxTotal.Text)
Dim FundsAvailable as Int = 0
Dim NewWalletValue as Int = 0
Dim UserName = FormProfileMain.LabelWallet.Text
Dim qryWalletRetrieve as string = "SELECT wallet FROM TblMemberships WHERE Username = @username"
Dim qryWalletUpdate as string = "UPDATE TblMemberships SET wallet = @wallet WHERE Username= @username"
Dim cmd As New SqlCommand(qryWalletRetrieve, con)
cmd.Parameters.AddWithValue("@username", UserName)
con.Open()
FundsAvailable = (Int)cmd.ExecuteScalar()
If (FundsAvailable < FundsNeeded) Then
MsgBox("Insufficient wallet, please load!", MsgBoxStyle.Information, "Wallet")
Else
NewWalletValue = FundsAvailable - FundsNeeded
cmd.CommandText = qryWalletUpdate
cmd.Parameters.AddWithValue("@wallet", NewWalletValue)
Dim RA as Integer = cmd.ExecuteNonQuery()
If RA = 1 Then
MsgBox("Successfully ordered!", MsgBoxStyle.ApplicationModal, "Wallet")
Else
End
End
cmd.Dispose()
con.Close()