Payment System Design Document

Design Goals

The payment system enables users to pay other users for services, while allowing the site to take a cut of the transaction. The key goals of the system are:

  • It must be robust and flexible with regards the specific payment system used. Specifically we should be able to connect to systems like PayPal or Google Payments without affecting the other modules that rely on the payment system.
  • It must be flexible enough to allow unique business logic to be substituted and reconfigured easily. In particular, it should be simple to set rules about payment types, invoicing, rates and fees, and the access controls and privileges conferred by payment.
  • It must be simple to use and maintain and sidestep security concerns to the greatest extent possible.

Usage Scenarios

In order to design a system that maintains a high enough level of flexibility, I present the following hypothetical use cases, a number of which are based directly on customer requests, and others of which are based on my own thoughts for what he might eventually request, and might be difficult if we design the system too rigidly.

One-Time Content Purchase

In this simplest of all scenarios, a seller places a piece of content online, along with a purchase price. The user can purchase the content for a one-time fee. As soon as the user pays for the item, he or she can view it on the site.

One-Time Application Fee

In order to access some parts of the site, the user must first pay a one-time application fee to register. The details of how registration will be remembered and recorded are outside the scope of this specification (they don’t pertain to the payment system)[1], but the handling of the payment process and the verification of payment do pertain to the payment system.

Expiring Content Purchase (aka Content Rental)

Perhaps some content sellers will want to post their content so that users can view them only for a limited time. Aside from various DRM issues[2] related to ensuring that this really happens (i.e. preventing users from permanently downloading unprotected content), we also will need a system to expire permissions on content after a specified period[3].

Purchasing Access to All of a User’s Content

Suppose a content producer wants to allow users to pay a one-time fee to purchase all content, or perhaps a set of content, including access to newly added content. This is implemented by making sets of content inherit permissions from parents that correspond to these content groupings. Then by selling access to the parent objects, the user, through inheritance, gains access to all of the children.

Recurring Access Payments (aka Monthly Fees)

For access to some services, the site may require users to pay a monthly fee. This applies both to content and to restricted services like posting for-pay content. This can be implemented by a combination of an expiring access and either discretionary or role-based access control for restricted operations[4]. Additionally, it is likely we’ll want some sort of automated billing system, which is the main extension required by this use case over the previous ones.

For instance, say NBC wants to post all of its TV shows to our site, and for a flat rate of $5 a month, users can have access to all of the shows (to watch, download to Zune or iPod, etc.). As addressed in the above use case, we need the ability to group all of NBC’s content into a bundle which can have its own access rights which filter down into child objects. Then user’s can purchase an expiring access to this bundle which they can renew on a periodic basis. The real question is whether the user can set up an automatic renewal of the content access to extend his or her rights for another month by automatically billing his or her account. I see this as mostly a stretch goal as it involves a lot of user interface work as well as a triggering system to automatically trigger events at certain times (like once a month), but I think we will eventually want to do it.

Private Lessons

Another usage scenario involves paying for a private lesson. This is more complicated, as it is unclear exactly what role the site plays in ensuring fulfillment from both parties. Unlike content purchase, the payment is for a service, and the service must be performed after the money is paid (at least it is likely to be). Perhaps the site can hold money in escrow until the service is performed, although this could become rather complicated. It seems likely that regardless of the system that is chosen, some type of conflict resolution mechanism will be applicable.

At its core here though, the site really doesn’t do much more than PayPal for this use case, as one user is simply transferring money to another with the understanding that a service will be performed. Certainly the site is the facilitator for connecting them, but there are no special requirements on the payment system.

Sponsorship

This is more difficult to answer as the sponsorship concept is ill-defined, but presumably sponsorship will involve the transfer of funds in exchange for some alteration of a user’s profile to exhibit the sponsor.

Addressing these Scenarios

Ironically, despite the complexity of these scenarios, the payment system itself is mostly insulated from the details of what happens besides the transfer of funds. The payment system’s sole job is to set up transactions and to validate that funds are in fact transferred, as well as taking a cut for itself. The issues of how all of the necessary changes are made once a transaction goes through are completely isolated from the actual transfer of funds.

A slightly more relevant issue however, is dealing with integrating the payment interface into the site. The details of this are likely to be messier in general, and hard to encapsulate from the specifics of each payment method (i.e. PayPal, Google Payments, etc.).

The payment interface that should be used by the majority of code,Atelier.PaymentSystem.IPaymentSystem[5], needs only one function:

void TransferFunds(decimal amount, IUser payer, IUser payee, PaymentDelegate paymentSucceeded, PaymentDelegate paymentFailed);

This function is called with the user objects of the two user’s involved in the transaction, as well as the amount of currency to be transferred between the two users. For now, we will assume that currency amounts are specified in US Dollars, although we need to consult to determine whether and how currency conversion issues need to be addressed. Additionally, two delegates are passed in. The first delegate, paymentSucceeded is called if and when the transfer of funds succeeds. The second delegate is called if the transfer of funds fails. This interface assumes that the accounts of both users have already been linked to the payment system used to transfer the funds. Assuming the funds are directly transferred between the two parties, this must presumably be the same system. It is also possible that the transfer will occur as a two stage process: money is transferred from the payer to the site, and then the site transfer’s funds to the payee. This system would allow users on different payment systems to transfer funds through the site. A disadvantage of the above interface however is that it requires the payment system to be able to figure out which payment system to use if the user has linked multiple systems. We may need to augment the above call with additional info passed along from front-end user interfaces to the payment systems about account details. These interface modifications will depend on further investigation of the specific requirements of the payment systems we need to use.

The key thing to note here is that using delegates for payment success and failure allows the business logic of what happens once the payment goes through to be separated from the actual payment process. Thus the code to do a content purchase can create a delegate that will set all of the permissions appropriately and pass it in to this interface. Then that will get called and set the appropriate permissions as soon as the payment transaction succeeds.

[1] See Appendix B of the Access Control System Design Document

[2] See Appendix

[3] See Appendix A of Access Control System Design Document

[4] See Appendices A and B of Access Control System Design Document

[5] See IPaymentSystem.cs in the PaymentSystem project