I am using the SIM method. I find whenever any error occurs (eg. card declined) my relay response is called. I would prefer instead that the user stays on the authorize.net payment page and is given the option to fix card details or choose a different payment method. I find that whether I set x_relay_always to true, false, or don't set it at all, the behaviour doesn't change. I always get my rely response invoked and the user is never given any opportunity to try again.
The documentation for SIM suggests the behaviour when x_relay_always=false should be otherwise. Quote:
If a transaction encounters an error or is part of a partial authorization, and you are using Relay Response, the Authorize.Net payment form reappears, offering an option to try again or enter another form of payment to complete the order.
This field instructs the payment gateway to return a relay response regardless of whether there are any declines, errors, or partial authorizations.
It seems to me that x_relay_always has no effect and the behaviour is always as if it is set to true.
How can I have authorize.net handle card declines and allow the user to try again?
If a transaction is completed (either with approval or decline), then the relay response will always occur. The x_relay_always option was created to give developers more control in cases there the transaction was attempted but did not really complete. One example of this is if the cardholder were to put in an expiration date from the past. The default behavior in this case is to reload the payment form and allow them to update the information. With x_relay_always on, the customer will instead be directed to the Relay Response code with a reason code of 8 indicating that the card has expired. There are similar scenarios for other fields that can be detected as invalid without actually running a transaction.
The other important use case for x_relay_always is the occurrence of a partial authorization. In the case of a partial Authorization, our default behavior is to allow the customer to enter a second payment method to complete the transaction. With x_relay_always set to true, we would instead send the partial authorization results via relay response and allow the developer to choose how to proceed.
Ok what you say makes sense, although it seems unintuitive to me. I think it's reasonable to read the documentation and assume that transaction declined should not invoke the relay response. I see now why Authorize.NET does not treat transaction declined as an error. I'm saying I don't like it.
With other payments gateways I have worked with, a card declined will be displayed right there on the payment form, and the user is able to try again. It is less alarming for users (who generally NEVER read the actual message we display) and creates less supports calls for us. I worry that as a result there are more abandoned sales with Authorize.NET.