Spree Gateway uses ActiveMerchant to assist in communications with Sage Pay. The code which adds the CV2 value to the Sage Pay request is located here:
You can find your ActiveMerchant code location by executing:
bundle show activemerchant
and add in some debugging there. If you follow the stack trace up, you should be able to find where the credit card object is coming from, and why it's not being populated with the correct value from the Spree credit card.