For many projects, there comes a time when you want the site to make a profit.
And not only in the form of payment of advertising banners or contextual advertising, but also in the form of money from its visitors.
No matter what they offer - a cool special effect on an avatar, a T-shirt with the symbols of the project or access to private messages of the first beauty of the site. It is important how to get money for it. And it is desirable immediately, until the user has decided not to spend their money.
Such a restriction immediately leads to deletion from the list of payment methods filling out a receipt in Sberbank. Yes, this is also a method, but the method is not fast. Especially if it's late evening outside, the user relaxed over a
bottle of beer with a cup of tea. What a Sberbank, to take it lukewarm, lukewarm!
')
What are the ways to organize the reception of more or less instant payments come to mind in the first place? Personally, I just came to mind three at once:
- SMS
- plastic cards
- electronic money
Each method has its own advantages and disadvantages.
Payments via SMS - a big commission, but almost every user has a mobile phone.
Plastic cards are not common enough (yes, yes, the residents of Default City, there is a life outside the Ring Road, too, ready to pay!), But the commission is minimal.
Electronic money - a lot of different systems, technical and legal difficulties of connection, but the audience is big! And how to replenish!
Not stopping in this article on the first two methods, I want to talk about the organization of reception on the website of electronic currencies. Such as
WebMoney ,
Yandex.Money ,
Money@Mail.Ru and the like. We don’t care about the implementation of work in each specific case, you can read about it in the documentation for these payment systems (PS), and in various kinds of success stories and failures.
The main idea that should arise after reading the article (and I hope it will arise) - having correctly designed a payment acceptance system, it will not be difficult to connect each new system.
Immediately make a reservation, further under the "account" I will understand not the account , but rather invoice . And for convenience, in order not to be confused between the user's account, which contains information about payments, the size of the user's payment balance, etc., and the invoice for payment of something, I will call the latter the “application” or “order”.In general, the payment systems that I have come across are divided into two types:
- independently informing the seller of the fact of payment (as a rule, sending some data in the background to a pre-specified URL).
- and systems that need to be polled for payment status.
The implementation of the scheme of working with both types is almost the same, but the first one is much simpler - it is enough to somehow separate the order number in our system from the data stream and call a single function that changes the status of the request to “paid”.
Therefore, let's talk about the second.
A typical scenario of working with such systems from the seller’s point of view is as follows:
- initialization of the payment process by the user, saving of the request for payment
- Formation of an application based on our billing data, signature of an application with a secret key or certificate
- sending data to the payment system and getting the order number in their accounting system
- saving this number in our system
- questioning the payment system to change the status of this order
- change of application status in our system, user service
If we are talking about payments, then of course, to account for payments / user requests, some kind of billing is needed. It can be arbitrarily complex or simple, for us it can be a “black box”: we only need two things from it: the amount of the application and its number.
I think you should not specifically discuss why this number should be unique, right?
The rest of the billing data (for example, some textual description of the service) is optional.
How to write billing correctly is a speech for a whole group of articles, so now it’s not about it.
Who wants, questions about billing can ask me in private or by mail.
So let's start with a common architecture.
As it does not seem strange, the recipe for the architecture of the payment acceptance system according to the described scenario is very, very simple. We will need:
order queue - 1 pc.
queue processing dispatcher - 1 pc.
general library of work with applications - 1 pc.
common web interface library - 1 pc.
general library of work with payment systems - 1 pc.
libraries work with specific payment systems - N pieces, by the number of systems.
Now more about each of the parts.
1. What is the queue of applications?Everything is simple - this is a table of applications of various statuses (in the simplest approximation - “paid”, “unpaid”, “in processing”). We will need it both in order to save information about the application, and in order to understand which applications need to be sent for processing to the dispatcher.
Readers who have already learned the words “normalization” and “relational database” will argue that there should be more tables, but I argue that one is enough.
2. Manager queue processing.This is a kind of script running in the background as a demon or just crown, it does not matter.
Its task is to process the queue of applications, access payment systems and change the status of applications.
3. Library work with applications.In essence, this is a library for working with queues (read the “database”). It just needs a few functions:
- creating application
- getting information about the application
- Change in status and other application data
- getting an application from a queue
- removal of application
4. Web interface.For what it is needed, it is clear - to display information about the order to the user and so that the user can click on the “Pay” button.
From this library you need to be able to give the same data from several formats: at least html and json / xml. HTML is understandable for what, and JSON is for using AJAX and not overloading pages. In principle, it is possible without it.
From the web interface, only 4 functions are needed:
- call creation request function
- call the function of obtaining data on the application
- call delete order function
- and basic error handling and data output in the right format.
5. Libraries of work with specific payment systems (BPS) should be able to
- generate the URL and data for the request to create an application in the PS.
- parse the answer of the payment system and return the order number in the numbering of the payment system
- generate URL and data for request status request
- parse the response of the payment system and return the status of the application.
6. From the general library of work with payment systems (OB) you will also need a little:
- a function to receive data from BPS, which is necessary for creating an order, and sending this data to the payment system.
- function to send a response to the BPS and receive from there the status of the application
- function for working with general settings (for example, information about connected payment systems)
How to change the described scenario of work in the new terminology?
0. User initialization of the payment process.The web interface displays a list of available payment systems and payment information.
The user presses "Pay", an order is created with the status "new", information about it is placed in the queue. At this moment, the user is issued a message “Sch everything will be, wait” and check the status of the application from time to time. Here you will need the same data about the application in JSON - while we draw the user on the screen all sorts of watch, progress bars, etc., using AJAX we query the queue about the status of the application.
1. Formation of an application based on our billing data, signature of the application with a secret key or certificate.
2. sending data to the payment system and getting the order number in their accounting system
3. saving this number in our system.
The dispatcher removes the application with the status “new” from the queue, sets the status “in processing”, transfers the data to the OB, receives the data necessary for sending to the UA. Sends them, receives the answer, gives it to the OB, the one in BPS and receives the order number. Saves the order number and URL for payment in our turn, puts the request status "ready for payment".
At the next survey of the user's queue, we throw on the URL to continue the payment. What he will do there is his business. In case he realizes that he doesn’t have this e-currency, on the page with the order status, we’ll give him a link to delete the order and create a new one with the ability to choose another currency.
4. survey of the payment system to change the status of the order.Periodically, the dispatcher receives an application in the “ready for payment” status and checks its status in the payment system. If the status does not change, put the application aside until better times.
In a good way, you need to consider the "shelf life" of the application, so as not to interrogate the payment system indefinitely.
5. changing the status of the application in our system, providing services to the user.As soon as the status has changed, the dispatcher marks the request as “paid for” or “rejected” depending on the payment system’s response. More she will not get to the dispatcher. Now the background billing scripts will receive information that the invoice has been paid and will render the ordered service to the user.
What is good about the described system?1. It allows you to perform all operations with the user extremely quickly.Saving the application to the queue, obtaining data on the application by a unique number is a very fast operation.
All slow work is performed by the dispatcher in the background.
2. It scales well.We can organize dozens of queues using various partitioning methods.
Tens and hundreds of demons to handle each queue or status, or currency.
3. It is simple.Connecting a new payment system is just adding a new library, which should be able to only 4 things described above.
I do not voice the specific implementation details in this article - the tools are unimportant.
This can be Perl or PHP, or Python for the web / work with the database.
This can be MySQL, or SQLite, or Oracle, or PosgreSQL for queuing.
This can be file_get_contents (), LWP :: UserAgent or CURL for working with HTTP.
You can double the polling interval of the request status in the payment system by half. You can in 3.14159 ...
The implementation is yours.
upd: The full text (including diagrams and additions) is posted
on my website