UPDATE: If you've come here looking for information about integrating PayPal into Community Server or about paid subscriptions for Community Server, I and several other Community Server technical evangelists have put together a product named Four Roads Commerce. You can find information about it at the Four Roads website.
We established earlier that we want to use PayPal for transactions but leave ourselves room for adding other payment gateways. We need something in between our application code and the PayPal SDK, so that we're not locked in. And we don't want to over-engineer.
At the same time, we also need to configure gateway-specific settings for a community.
Let's define an interface named IPaymentGateway and another interface named IPaymentSettings. Note: The regions and comments have been removed from the following code in order to reduce clutter.
public interface IPaymentGateway
{
string Name { get; }
string SettingsPage { get; }
System.Type SettingsType { get; }
IPaymentSettings CreateSettings();
}
public interface IPaymentGateway
{
string Name { get; }
string SettingsPage { get; }
System.Type SettingsType { get; }
IPaymentSettings CreateSettings();
} The IPaymentGateway properties give us the Name of the gateway (e.g., "PayPal"), the name of the ASPX page that we can use to configure the settings, and the type used to instantiate the settings. There's also a method named CreateSettings that will give us a new object in which to store settings for the gateway.
The IPaymentGateway properties give us the Name of the gateway (e.g., "PayPal"), the name of the ASPX page that we can use to configure the settings, and the type used to instantiate the settings. There's also a method named CreateSettings that will give us a new object in which to store settings for the gateway.
Down the road, we'll add properties and methods specific to carrying out a payment transaction. For now, we're mainly concerned with settings.
Why make the settings an interface instead of some name-value bucket? Because they will probably change depending upon the gateway. And I may want to write settings-related logic that is specific to a gateway.
public interface IPaymentSettings
{
IPaymentGateway Gateway { get; }
string ProductVersion { get; }
int SettingsID { get;set; }
string Description { get; }
void SetGateway(IPaymentGateway gateway);
}
The IPaymentSettings interface tells us its parent gateway, the version of this product creating the settings (for upgrade purposes later on), and the SettingsID of the community with which it is associated. In addition, it has a Description property so that we can display a summary of the settings to the administrator and a method that lets us set the parent gateway.
What's implied here? Why does the gateway need to tell us the type of settings to create and the page for their configuration? Why does the IPaymentSettings interface have a SetGateway method?
There's the model we're following (i.e., unknown number of settings that may vary per gateway) but it's also influenced by how the settings are to be persisted.
If you noticed in the post about multi-site support, Community Server (CS) writes its settings as XML to a field in table cs_SiteSettings. What other choices are there? You could create a table having a field per setting to be persisted. Or you could have a table where each record is a name-value pair. Maybe there's another option, but I can't think of it.
We have the same issue except worse. I'm assuming the settings for a gateway will vary from one vendor to another. So having a table that has one field per setting would be a maintenance pain. And having a name-value table could be unwieldy.
At this point, it seems best to follow the example in CS and write the settings as XML to a field. If we continue to follow CS's example, we'll need to persist that data through a custom data provider.
Guess what's next?
--
Sean Winstead
Tags: CommunityServer