I recently did some work for a client to design and integrate a shared payment system. The main specification was to use USA ePay as the payment solution provider, and that no PCI SAD data was to be managed by the clients machines.
Since the client requesting the work is a small startup, minimizing cost and keeping as far away from customer credit card information as possible was very important. With this in mind, I would need to implement a solution that allowed the business to accept credit card payments on a website or application without doing any redirects and making it appear the payment form was hosted entirely by the business.
In the PCI world, this implementation is known as the "Fully Outsourced iFrame" model and involves placing an iFrame hosted by the payment solution provider onto a webpage. This iFrame would then handle all of the interaction with the customer in terms of credit card information.
Here is a diagram of the official PCI security standards document illustrating what this implementation looks like. The different groups below correlate to what the client is responsible for in blue, USA ePay systems in green, and the customer web browser in grey.
Several different technologies will be used and need to work together in a single bounded context to process a credit card payment.
The majority of the work going into this system is going to be done in the .NET layer.
There will need to be some service to accept requests for creating and modifying the payment, as well as some way to get information about a particular payment, or a customer relating to a payment.
Another concept to keep in mind here are relationships of bounded contexts. Looking back at the diagram above, there are 3 contexts: an order (represented by Checkout & Order Processed), a customer, and a payment. The payment context is not as obvious as the other two, but it would need to be represented as something tangible at any given point in time in order for the order and customer domains to do operations against it.
Also, the payment system assumes there is already an order-taker system in place that has knowledge of a price to charge / refund and where to go to get information about a customer.
Connecting the payment domain to other order domains and serve as a singular place where all the order domains interact with a set of available interfaces wrapping the payment solution provider.
These interfaces will ultimately allow the Payment Domain implementation to be agnostic of any particular payment solution provider and seem transparent to the Ordering Domains.
The payment form will be created using React / Redux to take advantage of all of the rendering, middleware processing, and state management.
With so many things happening in the JS client, trying to design a system such as this would require a large amount of code just to keep events and processes synchronized.
The JSON-with-padding technique will need to be used here since a browser client will need to make a call to an external domain. Currently, this is a no-no as far as web-standards are concerned given cross-origin-resource-sharing, however this technique is sort of a loophole.
I won’t get into the particulars of how JSONP works, and instead leave that as an exercise for the reader, but in short this is the piece of code that will communicate directly with the payment provider. The legalities and requirements identifying payment systems deems this to be an acceptable footprint, and does not put the responsibility of ensuring credit card details are secured on the implementer, or my client in this sense.
The only way to avoid having to use JSONP would be to have reliable correspondence with the payment solutions provider and have an exception made where the hostname of the payment form is allowed. In my experience however, things like this don’t happen and integrators need to resort to tricks such as this one.