Ok, so about a year ago I wrote a web app that helps organize appointments for my dads company. He now "couldn't do business without it". I have decided that I want to build a SAAS subscription model out of it and open it up to the public.
It's currently built on codeigniter and php which I do not think is a good fit for a SAAS version. I am planning on rebuiling it from scratch in laravel 4 and using stripe as a payment gateway.
My concern is how best to handle the database / application structure for more than one client. Currently, it just serves the one business and is very un-abstract and is specific to my dads companies needs. I need it to be able to handle different data depending on what the business who uses it does.
I have looked into multi-tenancy but i'm not sure this is right for this. I am thinking that a 'gmail' style approach would be better. One app / domain that after login the user will see their customised dashboard and only their data.
Before I get stuck in with the coding I need to work out how best to handle multiple 'accounts' on the one database. I do not want to create a table for each user, nor a database for each user.
I guess my question is can anybody point me in the right direction for how best to handle a monthly payment subscription in Laravel? It's not so much the code that I'm stuggling with, rather what exactly I would need to build to handle charging the customer each month and denying them access if billing failed etc.
Thanks
You are in for a lot of reading and a ton of work!
First of all, let's completely ignore the billing aspect of this for now — at the end of the day that portion of the application is really fairly trivial. Take a page out of 37signals Rework (page 93 and 94) and launch your product with a 30 day free trial before you even begin implementing it (you should know how to implement it by then).
Second, why do you think that "gmail" doesn't use multi-tenancy, URI structure tells nothing about the underlying database structure. I'm fairly confident they aren't cloning a database schema for every one of their customers. Therefore you've probably answered your own question — you want to implement multi-tenancy.
You're going to want to abstract your database (and application architecture), and honestly there is no better resource to help you on your way to doing that than Taylor Otwell's (creator of Laravel) book Laravel: From Apprentice To Artisan. His book is not for beginners, and by the time you're done reading it you should probably be able to answer this question for yourself.
You are not going to be creating a table or a database for each user, you aren't even going to be creating one for each organization. Instead you'll be creating abstract database structure in code, which will pull your users data out of the database.
Think about checking for permission to access an organization as another layer of user authentication. On every request you'll be checking to see if that user can access a particular organization. You'll likely also check to ensure that organization is still active (did it expire because they didn't pay?) this will again happen on every request and likely with a filter within laravel.
This really leads to the next very important factor of developing a SaaS application.
I don't know about you, but I'm paranoid, and I couldn't sleep well at night if I wasn't sure that user number 4506 couldn't see the data of an organization that he doesn't belong to. The only really good way to ensure this is through unit testing, which I'd highly suggest learning if you haven't already.
The best way to do this within Laravel 4 is to read Jeffrey Way's book Laravel Testing Decoded. This book is extremely advanced, but still easy to understand if you have a good grasp of the fundamentals.
Last but not least, the number one thing is get involved in the community — the easiest way I'd suggest doing that is idling on the #laravel IRC channel (freenode). Ask some questions, maybe answer some questions, everyone in the channel is very nice and responsive.
You are definitely in for an adventure, don't be afraid to ask questions and make mistakes. Good luck.
As a rough overview, I would have a clients table, and a subscriptions table. Any other data that needs storing such as contacts, or appointments, can be associated using foreign keys to the client table.
In laravel, you can use the ORM to get the currently logged in client, and then through a relationship, fetch appointments and contacts belonging to them.
There are some useful tools for laravel at cartalyst.com, including sentry and sentry-social for user auth, and integrating user accounts with facebook/google/twitter, etc.
Stripe will allow you to configure recurring payments, and will notify you via web hooks each time there is a payment attempt. you can log these in the payments table, and associate them with a user/client. you can use this to keep track of who has paid, and how recently.
Also, bear in mind that you may not want to cancel the account immediately on failed payment.
Stripe will reattempt, and it may be that your best response is after it is two or three days late, or you get an invalid card notification,to get in touch with the client and prompt them to update their payment details.
It may also be an opportunity to check when they last logged in.
If it was over a month ago you can credit them with a free month, and remind them of how much your app can do for them.
By doing this, you may be able to get people to continue using (and paying) for something they had forgotten they had subscribed to.
Related
I am trying to figure out a reliable data architecture for a small business that wants to utilize Shopify for their online store.
My current idea is to have a central database (doesn't matter which, we'll say Postgres). The business users can create products, services, customers, etc in Shopify. Customers could go to their site and order things.
Then I would have a background process to sync all these things from Shopify to this central database.
Some orders would have to be put in a LIMS system so I would have another background process to sync these orders in the central database with the LIMS system.
Some orders come directly from the LIMS system so another background process to sync these orders to the central database.
All the orders in the db need to be synced to Quickbooks so another background process to sync this.
Concerning Shopify, does this seem like a doable strategy? I'm an experienced programmer, but no experience with Shopify or its APIs.
Also, I'm not really a fan of syncing data sources but...is there a better way?
Obviously I could write an admin ui to let them create things in the central db first and then sync them to Shopify.
But isn't the whole point of Shopify to make this part easy by providing them a way to create all these things right out of the box?
One of the other things that they want is to run reports against this central database. In theory Shopify could act as the central database, but not sure what reporting would even look with Shopify API.
My advice to you is to use Shopify till you understand it, and once you do, you may find things that Shopify cannot do for your business. Only then would you marshal any resources to try and fix those problems with custom code. As it stands, your question is one of "how would I..." for problems that do not exist for you. Why bother thinking about problems you do not have? Wait till you actually have a problem, then ask a question about how to solve it.
I work for an app that store some health datas and the law and our ethic make us respect some rules about the treatment of personnal datas.
We want to store the health datas of our users in a different database than the personnal datas (especialy the name of the user). The goal is that if a hacker get access to the health database/server app, he will not be able to get the identity of the persons. And if he get access to the personnal data database/server app, he will not be able to get the health informations of the persons.
Anyone in my team never made this kind of thing, the client proposed this kind of structure
The goal is to have a middleware that manage authentification and provide the id of the personnal data database with the other one.
In my mind, we could make far better by using some asynchronous tricks but i'm not an expert in security and i only have a confused idea of what i could make. Maybe there is some standard solution that is used in this kind of situation.
It would be realy great to have some advice of the community about this problem.
I recently read a tweet that suggested that if one wants to avoid headaches in the future of an app, they should have the user table have only authentication information and a user profile table for everything else. That is if you have bikes and peaches in the system they should be linked to the user that owns them via the user profile id. The tweet was not clear on what the consequences of using the user profile. Are there maintainability/scalability repercussions to not following this especially in a large web app?
Well, don't take it as a dogma, though it isn't completely worthless. Dependency is a problem: if you have to have a lot of different data that represent particular user, you'll change underlying database oftenly. In case everything is stored in a single column, you might find yourself doing repetative monkey job of "making it work" with your types/ORM and whatsnot gonna be involved in DB <-> RUNTIME communication.
It is all about splitting complicated task into smaller less complex subtasks: auth is self-standing - one of the most important - task itself and it definitely deserves some dedicated space. However, your app might be not that big, or not that concerned with users, and thus it won't be very helpful to split data into multiple columns. You must develop a deep sense of purpose and measure when it comes down to a software design.
I'm working for a startup and we have a customer who uses Demandware for their online store.
Our company provides vouchers which are worth a specific amount of money. So customers on the retail site can enter the voucher number near the end of the checkout experience and if it's worth, say, 10 dollars, their shopping cart is updated (-10).
I have the CTO saying we just need to "drop a few lines of javascript" onto the retailer online store. But I think this requires a Demandware plugin (especially updating a shopping cart), which involves signing up for a developer or partnership account (which takes some time), learning Demand Script and building the plugin, then releasing it to Saleforce's app store. Am I correct? Is this the only way to achieve this?
Just to be clear, the functionality is: the voucher code box needs to take a voucher number, an API request is made to our service to check what it's worth, then update the cart.
That's a pretty broad question but I'll try to explain.
First off, Demandware has gone all JavaScript.
But yeah, it has a huge API so the process sounds about right the way you've described it.
Ask your client whether they have a service integrator they're working with, because that would be their job. Your job would be to provide an API so that Demandware can check whether the voucher code is valid.
Demandware is a closed community so it's unlikely to learn it unless you're working in a company that is doing Demandware development.
Oh, and if it somehow ends up being your job to develop this, a tip from me - you probably need to get access to their site's files and use the LineItemCtnr class to createPriceAdjustment() :)
The first tip from me is that Demandware got bought by Salesforce and is now branded as Salesforce Commerce Cloud, so if you hear either, they are the same thing.
You are right that you are going to have to work with Salesforce to get going. They are a cloud provider and there is no self-hosted version of the platform, so in order to do any development, you need to have a relationship with them.
So then it depends on how you get access. If the client has any sandbox environments they are willing to share with you, you could do this as a custom build working in their environment, modifying cart code to make the service call as you ask and as the previous response suggests. But then (depending on the terms you have with the client) your company may or may not be able to reuse that code for other clients. You will also have to work with them to get that integrated into their existing site, get it deployed through their processes, etc.
If you want to write something that other Commerce Cloud clients could use, then you should set up your own partner relationship with Salesforce and get a software package they call a cartridge to what they call their LINK marketplace, which is basically a big clearinghouse of integrations like yours.
Technology-wise, the platform has gone through some changes recently, going from an XML-based GUI tool to specify business logic to using CommonJS scripts to define them. If your client is a new client within the last year or two they probably have this new fully javascript implementation, but if they are an older client than that they may be using the old way, which has a steeper (read: more proprietary) learning curve.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
what i have until now:
session on server side
unique id (md5) of computer created by Request.ServerVariables("HTTP_USER_AGENT") & REMOTE_HOST and saved on the database
but what else can i do in this case? users continue to share their login details :(
This is a problem in almost any line of work: from software, where someone can simply copy the program, to simple ticketing, and having an individual walk past the ticketing desk. (I worked in a ticket selling position, and we did have individuals walk in without paying.) This is largely a social problem, not a computing one, and it's been my experience that trying to fix social problems (people) with computers is largely futile. Here is a culmination of what I've heard on this topic, and the two categories the advice tends to fall into:
Try to control the problem.
Try to somehow identify and control the unscrupulous users of the system. This can be DRM for software, or a security guard in the example of the ticketing desk. This is essentially what you're trying now.
A problem I see with your current method is it doesn't support multiple browsers. I routinely browse from multiple browsers, and from multiple websites. If this is your method for identifying theft of your service, are you sure you're not seeing false positives?
If you do try to control the problem, the best thing I've heard is to make sure you don't affect the users legitimately using the system. Causing pain to a legitimate user by either making him install DRM software on his machine, or by requiring him to take off his shoes to get on a plane, only causes him trouble and degrades the apparent quality of your service in his eyes. Try to find ways to identify troublesome users without affecting the normal crowd: selecting blacklisting (banning) of IP addresses might be effective in the case of a web service. (Wikipedia controls spammers and malicious editors this way, and some people have controlled spam email this way.)
Now, the other line of reasoning:
Ignore the problem.
This stems from the "don't get in the user's way" ideals. Make your service as good as it can be for the user, and offer him a high quality service that he won't mind parting with his cash. In other words, make it worth his money. This depends on enough people being honest that you're still profitable, of course. Some argue that those who steal a service often wouldn't have paid for it anyways.
In reality, some mix of the two is probably the most effective measure.
Number two doesn't work. I login from at least five different devices. You definitely do not want to couple yourself to the hard- and software upgrade cycle of your customers
Get an cell phone number of user and send SMS with one-time password each time he tries to login. Email wouldn't work because it is too easy to share.
But you can see a great decrease in your user count: this thing is REALLY annoying.
The way I prevent users from sharing account information is by prevent multiple logins from one location. So if the user logs in, it will log out all other sessions.
This is relatively easy to do. Associate to each user in the database a field like session_key that is randomly generated on login. Store that session_key in the database AND in a cookie in the users browser, and check that the session keys match. If not, log the user out. Whenever someone else logs in, it generates a new session key, thus inactivating all previous sessions and logs out the user. You can also try keeping track of other information as well, such as the users IP address, etc associated with the session. It's not 100% foolproof, but it prevents most users from sharing accounts.
Log the IP addresses, times and usernames in a database table. Check the database for users that are active from more than one IP on the site, and ban those users.
Or, stop users from logging into an account if there is a session already on the server for that user.
There is no way to prevent this. You can only make it more difficult - But you should consider the downside: Legitimate users get caught in the crossfire. If I were you, I'd simply tackle the source of the problem - The reason you don't want people to share logins - And fix that instead. Make an incentive not to do it. Remove advantages for doing it.
The only way to stop the users from sharing something is to make that something non-shareable (at least not with some serious hacking). But this involves hardware which can be not appropriate for your project. I am talking about hardware cryptotokens, which hold private keys and don't let one copy them. If you give your user such token with the private key inside, the user can pass the token itself to other person, but he can't copy it.
That's simple. Use the 10 to 15 favourite questions and their answers during registration processes. Ask randomly one of them during each login.
now i think it is a combination of several factors if not all that can work
lower the subscription costs
prevent multiple sessions at the same time
use two factor auth
if app disable screen shots...make too much content on single pages to make it tiresome for someone to scroll down taking screen shots..disable screen recording if possible.....offcose by not giving any permissions
i think considering fingerprint scanning and face recognition hand in hand with device ids can work
lastly consider loading your website in a webview based app for android users