The controller provides a hardcoded Profile instance for now (we get the submission URL from the Profile - it could be the Cybersource test URL or live URL). That's ok for the purposes of this story, but we'll need to think through the use cases to come up with a more flexible way to do this. In the case of Penn, their situation is to have potentially many shopping cart forms (each with its own profile), but they all use the same credit card form. The shopping cart form precedes the credit card form, so I was able to set the profile in the shopping cart form and pass it to the credit card form. We'll need to handle use cases beyond that.
I played around with having a non-persisted model to go with the payment form. This would let us take advantage of Rails validations (at least up to the point of submission) and make form rending easier with simple_form. But I decided against it because A. I didn't see a way to get the input fields in the format Cybersource wants (i.e. not in a hash named after the Rails model) without juggling names in JavaScript, and B. we may not want to entangle the gem with simple_form.
Following up on my last message, I'm happier with where we are now on these two issues:
Greg suggested using a config file and an initializer for keeping track of Profiles (we don't want sensitive data in the db if possible). This provides a nicer structure. Now, in the controller, you pass to the Profile model the Cybersource profile_id of the profile you want to use for the credit card form, which seems reasonable to me.
And I do have a non-persisted model now for supporting the credit card form. This helps with client-side validations (I'm just relying on HTML 5 validations at the moment) and makes it easier to use simple_form. I have some code in the model that helps with simple_form, but you can still use it without simple_form.
As a customer, I want to provide my credit card information in a web form, so that I can make my purchase quickly and conveniently online
Form fields:
Other: