Jump to content

Recommended Posts

Hello. I can use some help in figure out how to implement a "transaction".

I am building an e-commerce site where people buy subscriptions to online content.  When a person subscribes for the first time, the following things need to happen...

1.) Create a Member record

2.) Create a TOS record

3.) Create an Order record

4.) Create an Order Details record

5.) Submit payment details to Card Processor

6.) Receive the response from the Card Processor  (Hopefully a "Pass")

7.) Display an "Order Confirmation" page.

8.) Send out an "Order Confirmation" e-mail to serve as a 2nd receipt.

9.) Send out an "Account Activation" e-mail

My original plan was to wrap all of those 9 steps into a "transaction", so that if any of those steps failed, then the user would get a message during checkout like, "Sorry, your checkout could not be completed.  Please contact Customer Service."

However, I am also wondering if maybe that is too rigid?

What I don't want is a scenario where all of the records are created, but let's say the payment fails because the user is over his/her credit limit, and then I have an issue where a new "Member" has been created, but in essence I have an "orphan" because they cannot go back and try to re-register with another credit card because they are now an existing Member.

Even something as seemingly innocuous, like the "Account Activation" e-mail not being sent, would create havoc.

At  the same time, I don't want things so rigid that it backfires. 

Any thoughts on this?

 

Depending on your business needs, sure: you could do all of those at the same time.

But you're approaching this like it's all-or-nothing. It isn't. You can create the user regardless of the transaction. You can record the order regardless of whether the payment goes through. Don't treat it like it's all one big operation that you have to rollback/cancel if any one step fails - make each part work in its own right, just like if the user was in control of each step.

  • Like 1
4 minutes ago, requinix said:

Depending on your business needs, sure: you could do all of those at the same time.

But you're approaching this like it's all-or-nothing. It isn't. You can create the user regardless of the transaction. You can record the order regardless of whether the payment goes through. Don't treat it like it's all one big operation that you have to rollback/cancel if any one step fails - make each part work in its own right, just like if the user was in control of each step.

Well, my question is coming from a standpoint of not creating a nightmare for myself if things should fail - since I don't have a staff of people to clean things up.

Before continuing the discussion, if it were you, would you create the records in the database and then process the payment, or would you get the $$$ first, and worry about the other things later on?

 

 

 

 

Create the order. Can't process a payment on an order that does not exist. It starts in a pending state.
Process the payment. If successful, enter the successful payment and mark the order successful. If unsuccessful, enter the unsuccessful payment and give the user a chance to try again.

Data is good. If you have any, store it. Doesn't matter what it is, store it. Whether it represents something successful or unsuccessful or even if you don't know whether it's successful or unsuccessful, store it.

@requinix,

First off, to be clear, what makes this complicated is that as user is giving me $$ for website/content access.  So things sorta need to happen all at the same time.  (If this was just buying socks, it would be MUCH easier!)

 

Well here are some scenarios I am worried about...

If I create the Member records, and the payment fails (e.g. user is over limit), not I have a new Member entity and no payment.  The user cannot log in yet, because they haven't activated their account, PLUS I don't want them logging in because now they have access to my website and I didn't get paid!

If I take the payment first, and then inserting Member records fails, now I have $$$ but an incomplete Member.  Like above, they don't have a way to log in because this time the records didn't get created.

 

On a side note, how likely is it that any or all of this could fail?  Is that a valid concern on a busy server where maybe 10 people are checking out at once, of would this be a rare event?

 

I'm sorta leaning towards my original idea which is to create all Member records first - using a transaction - and then try and process the payment.  If the INSERTS fail, then I can roll them back and never charge the person.  And if the INSERTS succeed, but the payment fails, then I simply roll back the Transaction and nothing lost.  (If I do that, maybe I need to remove sending the email from the transaction, because once I collect the $$$, I cannot automatically undo that using a transaction.  So by pairing up the INSERT and the $$$ part, it's either all or none, but if the "Account Activation" email fails, that is easier to deal with manually.)

 

Thoughts?

 

Edited by SaranacLake
27 minutes ago, SaranacLake said:

@requinix,

First off, to be clear, what makes this complicated is that as user is giving me $$ for website/content access.  So things sorta need to happen all at the same time.  (If this was just buying socks, it would be MUCH easier!)

You're thinking about this in terms of whether they happen during the same request. Sure, they happen in the same request. But they still happen in a specific order, and it's that order you need to be focusing on.

Quote

If I create the Member records, and the payment fails (e.g. user is over limit), not I have a new Member entity and no payment.  The user cannot log in yet, because they haven't activated their account, PLUS I don't want them logging in because now they have access to my website and I didn't get paid!

You should separate the member from the payment. An account should be able to exist in a state where the user does not have access to all the content. Because the concept of a user existing on your site really is separate from whether they've paid money to access stuff.

In fact you really should do this: restricting people from using your website at all until they've paid is not as good a business model as allowing people to sign up and then convincing them to pay money. It might sound counter-intuitive, but generally if people discover they have to pay money to create an account then they're not going to do either.

Quote

If I take the payment first, and then inserting Member records fails, now I have $$$ but an incomplete Member.  Like above, they don't have a way to log in because this time the records didn't get created.

 

Yeah, that's backwards. Don't do that. Member first, order second, payment third.

Quote

On a side note, how likely is it that any or all of this could fail?  Is that a valid concern on a busy server where maybe 10 people are checking out at once, of would this be a rare event?

Ooh, a whole 10 people checking out at once? Ha.

The only reason creating a member should fail is due to duplicate information. Like duplicate email address. You can create a user atomically by attempting to create one and letting the database tell you if it failed.

This concurrency problem is yet another reason to do each step in turn: so if there's a problem with one of them then you don't have to redo the whole thing all over.

Quote

I'm sorta leaning towards my original idea which is to create all Member records first - using a transaction - and then try and process the payment.  If the INSERTS fail, then I can roll them back and never charge the person.  And if the INSERTS succeed, but the payment fails, then I simply roll back the Transaction and nothing lost.  (If I do that, maybe I need to remove sending the email from the transaction, because once I collect the $$$, I cannot automatically undo that using a transaction.  So by pairing up the INSERT and the $$$ part, it's either all or none, but if the "Account Activation" email fails, that is easier to deal with manually.)

Thoughts?

You asked for advice, I gave mine. You're free to ignore it. Not my business.

27 minutes ago, requinix said:

You're thinking about this in terms of whether they happen during the same request. Sure, they happen in the same request. But they still happen in a specific order, and it's that order you need to be focusing on.

Well, I do have the proper order, it's just  feel like this has to happen all at once, and you're not so concerned about that.

 

Quote

You should separate the member from the payment. An account should be able to exist in a state where the user does not have access to all the content. Because the concept of a user existing on your site really is separate from whether they've paid money to access stuff.

I guess I could make it so an account can exist but the user can only log in, but nothing else.  Again, juts seems like more complexity than I was looking for.

 

Quote

In fact you really should do this: restricting people from using your website at all until they've paid is not as good a business model as allowing people to sign up and then convincing them to pay money. It might sound counter-intuitive, but generally if people discover they have to pay money to create an account then they're not going to do either.

Allow me to clarify...

Everyone can visit my website without an account and view maybe 30% of the content but really with no real features (e.g. posting comments, sending IM's, etc.)

So I am doing what you advise above.

But the difference is that to do those basic things (i.e.. "try it before you buy it") you do NOT need an account.  That's the architecture I went with.

However, to be able to really get to the good stuff (i.e. the other 70% of the content and ll of the cool features I built), then you need a PAID account - because you either are a "visitor" with no account, or a PAID Member.

Which is why I am sorta nervous about the Checkout process going smoothly...

The wish is that you decide to pony up for a paid account, you choose a particular paid plan (e.g. Silver, Gold, Platinum), next you enter account details (e.g. username, email, password), then you enter payment details, and finally click "Process Order" and an account is created as soon as I verify I got your $$$.

What I want to avoid is that I create an account for you but didn't get your $$$, or I took your $$ up front but I couldn't reciprocate and give you a working account.

I guess I could set up entitlements so you could in theory have an account that you can log into, attempt to re-purchase stuff, but is crippled from being able to access anything, but that just seems like more complexity - and I already feel like I am designing a website above my skillset?!

 

Just to clarify, if I simply wrapped the Member creation part (#1-#4) along with the payment part (#5-#6) in a transaction, is there a sin in that?

I believe that would cover my concerns about being stuck with half-a-transaction.

Can you comment on that?

 

Also, you seemed to laugh at my "10 concurrent users" comment.  And you mentioned things like duplicate emails.  I think I have that covered, so is that to say that the chances of things puking - whether I wrap all of this up in a transaction or not - is slim?

 

Like I said above, I have really bitten off a huge chunk here, but the thoughts of running my own side company is a dream of mine!

 

Thanks.

Edited by SaranacLake
8 minutes ago, SaranacLake said:

Well, I do have the proper order, it's just  feel like this has to happen all at once, and you're not so concerned about that.

I'm not concerned about it because it doesn't have to be. Like you said, you feel like it has to be a certain way. I'm telling you that no, it does not.

8 minutes ago, SaranacLake said:

I guess I could make it so an account can exist but the user can only log in, but nothing else.  Again, juts seems like more complexity than I was looking for.

It's something separate from this to consider doing, but one that I recommend. But if you do it then you'll simplify some of this problem.

8 minutes ago, SaranacLake said:

Allow me to clarify...

Everyone can visit my website without an account and view maybe 30% of the content but really with no real features (e.g. posting comments, sending IM's, etc.)

So I am doing what you advise above.

No, what you're doing is allow anonymous access. I'm saying allow authenticated but non-premium access.

Give like 20% access for anonymous users to get people to the site. Allow 30-40% access, plus maybe a couple features, for authenticated users to get people to sign up. Allow 100% access for people who pay money.

This here is some fairly basic economics about funnels. Let people ease into your site until they're comfortable with the idea of paying money; making it a single step of "30% access and you have to pay to do anything more" is a cut-off that is going to lose you customers.

8 minutes ago, SaranacLake said:

However, to be able to really get to the good stuff (i.e. the other 70% of the content and ll of the cool features I built), then you need a PAID account - because you either are a "visitor" with no account, or a PAID Member.

Allow unpaid access. Give people who are interested in your site another step they can take that doesn't require them to pull out their wallets.

8 minutes ago, SaranacLake said:

Which is why I am sorta nervous about the Checkout process going smoothly...

Because you're fixated on the whole "omg it's all at the same time" thing that I keep telling you it is, in fact, not the case.

8 minutes ago, SaranacLake said:

Just to clarify, if I simply wrapped the Member creation part (#1-#4) along with the payment part (#5-#6) in a transaction, is there a sin in that?

No. It's dumb, but it's not a sin.

8 minutes ago, SaranacLake said:

I believe that would cover my concerns about being stuck with half-a-transaction.

Can you comment on that?

I don't see how what you're describing now is different from what you were talking about originally. Before you wanted to do everything "at once". Now you want to do everything "at once". It's the same thing, just different words.

8 minutes ago, SaranacLake said:

Also, you seemed to laugh at my "10 concurrent users" comment.

10 concurrent users is nothing.

8 minutes ago, SaranacLake said:

And you mentioned things like duplicate emails.

It's unlikely to happen, of course, but when you have everything "at once" taking a long time then you have to care more.

8 minutes ago, SaranacLake said:

 I think I have that covered, so is that to say that the chances of things puking - whether I wrap all of this up in a transaction or not - is slim?

For varying definitions of the word "slim".

8 minutes ago, SaranacLake said:

Like I said above, I have really bitten off a huge chunk here, but the thoughts of running my own side company is a dream of mine!

Congratulations. But you're describing stuff that everybody does differently. And they do it differently for a good reason: because it works better.

You aren't anywhere near a point where you can run A/B testing to discover for yourself what works better and what does not, so maybe set aside your own designs and take a look at what other websites do. Because they have done the testing.

  • Great Answer 1

 

8 minutes ago, requinix said:

No, what you're doing is allow anonymous access. I'm saying allow authenticated but non-premium access.

Give like 20% access for anonymous users to get people to the site. Allow 30-40% access, plus maybe a couple features, for authenticated users to get people to sign up. Allow 100% access for people who pay money.

This here is some fairly basic economics about funnels. Let people ease into your site until they're comfortable with the idea of paying money; making it a single step of "30% access and you have to pay to do anything more" is a cut-off that is going to lose you customers.

Allow unpaid access. Give people who are interested in your site another step they can take that doesn't require them to pull out their wallets.

That's a pretty major paradigm shift in how I designed things.

Where were you a year ago when I was trying to figure this all out?!  *LOL*

 

8 minutes ago, requinix said:

Because you're fixated on the whole "omg it's all at the same time" thing that I keep telling you it is, in fact, not the case.

No. It's dumb, but it's not a sin.

So why is that middle tier so important?

It's not like I am asking people to make a huge jump.  (Either you have $50/year for a subscription or you aren't interested or are cheap.)

And I have enough "teasers" on my site that, in my opinion, it shouldn't be hard to get people to go from anonymous visitors to paid member.

Do you have examples of companies where your suggestion would be clearer?

I get that you are saying I need another step, but I'm just wondering why that is so critical as you claim.

In my mind, going from $0/month to $4/month isn't a huge commitment.

Also, a lot of my website/business is based on what other (successful) companies already do with free vs paid content (e.g. New York Times, Wall Street Journal, Time, etc.)

Of course I am always open to new ideas.

 

 

8 minutes ago, requinix said:

Congratulations. But you're describing stuff that everybody does differently. And they do it differently for a good reason: because it works better.

You aren't anywhere near a point where you can run A/B testing to discover for yourself what works better and what does not, so maybe set aside your own designs and take a look at what other websites do. Because they have done the testing.

Does PHPFreaks do it differently?

Most models I have seen is "Free" or "Paid".

And to be clear, I *DO* offer different types of paid memberships, so it isn't as "black and white" as you describe.

I haven't set prices, but am thinking of starting off with:  $0/yr, $30/yr, $40/yr, and $50/yr.

 

 

2 hours ago, SaranacLake said:

Most models I have seen is "Free" or "Paid".

Free doesn't mean anonymous though, and that's the point.  You should have a way for members to create an account without having paid.  You kind of need one anyway for a scenario that it seems you haven't thought about yet.

What happens when someone does sign up and become a member and pays your $50/year fee, but then next year decides they don't want to pay again.  Now they are in exactly the situation you're trying to avoid.  They have a member account but haven't paid you.  Can't login because apparently that isn't allowed and can't re-register because their email is already in use.

You need to accept that once you decide to start charging people money things will get more complex and you have to deal with it.

The simplest thing to do is like requinix is saying and separate your registrations from your subscriptions.  Even if you don't want to do that middle tier as he suggestion and keep your cut off, make the determination of what a user has access to based on whether they have paid, not on whether they have registered.  This could be something simple like a HasPaid flag on their account (limited use) or more complex like a separate table to track subscription data (more flexible but more complex).

 

3 minutes ago, kicken said:

Free doesn't mean anonymous though, and that's the point.  You should have a way for members to create an account without having paid.  You kind of need one anyway for a scenario that it seems you haven't thought about yet.

But do I?  See my response below...

 

3 minutes ago, kicken said:

What happens when someone does sign up and become a member and pays your $50/year fee, but then next year decides they don't want to pay again.  Now they are in exactly the situation you're trying to avoid.  They have a member account but haven't paid you.  Can't login because apparently that isn't allowed and can't re-register because their email is already in use.

Right now I am trying to figure out all of the logic of membership/subscriptions/e-commerce, so pardon me if I misspeak.

In the scenario above, when a paid Member's subscription expires, they would (obviously) retain their account, and they would be able to still log in, however all entitlements would be removed, leaving them only with the option to do things like reset their password or change their email.

 

Anyone can got to the "Store" and purchase a subscription whether they have one of not.  So for the case where a Member's subscription had expired, they would have the ability to log in, go to the store, purchase a new subscription, and then their entitlements would be restored.

 

I think this addresses your valid concern?

 

3 minutes ago, kicken said:

You need to accept that once you decide to start charging people money things will get more complex and you have to deal with it.

What is complex is dealing with Memberships and Subscriptions.  (Selling physical products is much easier as far as logic goes.)

 

 

3 minutes ago, kicken said:

The simplest thing to do is like requinix is saying and separate your registrations from your subscriptions.  Even if you don't want to do that middle tier as he suggestion and keep your cut off, make the determination of what a user has access to based on whether they have paid, not on whether they have registered.

Well, I am doing that, I just haven't written the logic for that.

Each Membership Plan comes with certain "Entitlements".  So, for example, a "Silver Plan" might give you an "entitlement" to Post Comments, but a "Gold Plan" might give you the ability to Post Comments and Listen to Podcasts.

So WHAT you can do on my site is a function of WHICH Plan you purchase as each Plan has certain Entitlements.

But what I didn't build into my design - at this point - was the ability (or need) for people to create an Account without also purchasing something.  (And while I appreciate @requinix's thoughts, I'm not sure I agree that I need that middle tear - either people are serious to subscribe for $50/year of they likely never will!)

So I think what I am doing is consistent with you advice, @kicken, right?

 

3 minutes ago, kicken said:

This could be something simple like a HasPaid flag on their account (limited use) or more complex like a separate table to track subscription data (more flexible but more complex).

One reason I am bundling up Registration and Checkout is because I did *extensive* research on UI/UX design, and all of the experts say that you need to bundle Subscribing and Paying in ONE form/page/action or you risk losing people.  (Which was tough medicine to swallow since I spent a shitload of time building a registration modlue that mimicked the sites like PHPFreaks work, only to find out that approach is "outdated".)

So when a user chooses the "Gold Plan", I take them directly to checkout and ask them to set up an account, sign the TOS, and enter payment details all in one shot - per what the experts say to do.

Now I could offer people to "register" before they buy something, but to be honest I think that is pussyfooting and shows a lack of confidence in your product/service.

The Wall Street Journal's stance it "pay up or don't read our damn paper!"  And at least I am giving people maybe 30% access for free and without needing an account.  And if THAT isn't enough to entice people to get a paid Membership, then they aren't the people I am chasing

Which basically leads me back to where I am in my OP of doing Step 1: Account Deatils, 2.) TOS, and 3.) Payment Details during Checkout, AND I wasn't quite sure if wrapping that in a huge transaction was the best way to go.

 

@kicken, do you agree with @requinix that I need a "middle tier" of registered users who pay nothing?  (That is something I was trying to avoid based on years of experience online and seeing what pays off and what doesn't.)

 

11 hours ago, SaranacLake said:

In the scenario above, when a paid Member's subscription expires, they would (obviously) retain their account, and they would be able to still log in, however all entitlements would be removed, leaving them only with the option to do things like reset their password or change their email.

 

Anyone can got to the "Store" and purchase a subscription whether they have one of not.  So for the case where a Member's subscription had expired, they would have the ability to log in, go to the store, purchase a new subscription, and then their entitlements would be restored.

If this is true, then why is there a problem?  Make a users account, process their payment, and move on.  If the payment fails just don't grant them any entitlement.

 

11 hours ago, SaranacLake said:

One reason I am bundling up Registration and Checkout is because I did *extensive* research on UI/UX design, and all of the experts say that you need to bundle Subscribing and Paying in ONE form/page/action or you risk losing people.

Just because you put everything on one page for the user to enter their information doesn't mean you have to process it as an all-or-nothing thing.  You can still process it as separate actions and handle any problems appropriately.  For example, if the payment fails keep the account information and just send them to a payment form (similar to what you'd do for a member who's subscription is expired).

11 hours ago, SaranacLake said:

do you agree with @requinix that I need a "middle tier" of registered users who pay nothing?

You need a way for someone to be registered without an active subscription.  Whether or not that user can do anything is up to you.  Allowing a little bit of bonus abilities for simply registering is a common and good way to get people to hop on board.  Registered users are easier to track and  manage than a bunch of anonymous people.  If you ever want to do something like sell ads or potentially the website as a whole having statistics about usage will be very beneficial and registered users can give you some good statistics. 

 

  • Like 1
1 hour ago, kicken said:

If this is true, then why is there a problem?  Make a users account, process their payment, and move on.  If the payment fails just don't grant them any entitlement.

I don't know...  Maybe there isn't a problem?

I just haven't gotten to later design considerations like entitlements and how to handle re-subscribing - which I know is the most challenging part of all of this.

Put another way, I sorta need to figure out "A" before I can design "B", but as we are discussing here, I sorta need to understand "B" before I can finish "A".

That is why I find building all of this so challenging!

Okay, it sounds like I am still on track, I just need to think some of my design out some more, and probably circle back and refactor some parts like we are discussing here.

Thanks!

 

1 hour ago, kicken said:

Just because you put everything on one page for the user to enter their information doesn't mean you have to process it as an all-or-nothing thing.  You can still process it as separate actions and handle any problems appropriately.  For example, if the payment fails keep the account information and just send them to a payment form (similar to what you'd do for a member who's subscription is expired).

I guess originally I wanted a "cleaner" registration process with no unfinished business.  However, it might not be uncommon that a user genuinely wants to become a Member and subscribe, but maybe they thought they had available credit and didn't.  And to @requinix's point, it is better to capture any data and not make people re-enter things.  So if the payment failed, I could just route them somewhere and ask them to try another payment method.

This is still hard to get my head around since there is the whole "activation" part.

I guess if creating the Member succeeded, but the payment failed, then I could let them activate the account, but not give them any entitlements, and either befoe or after (??) they activate the account remind them that they still have to pay before they can use the website.

Maybe once I get to the entitlement part this will fall into place?

Lots to still consider!

 

 

1 hour ago, kicken said:

You need a way for someone to be registered without an active subscription.

I agree.

 

 

1 hour ago, kicken said:

 Whether or not that user can do anything is up to you.  Allowing a little bit of bonus abilities for simply registering is a common and good way to get people to hop on board.

Possibly, but one thing I am adamant about is that if you want to create a profile or post comments or send IM's, then you need to be a paid Member.  And I am unyielding on that so it creates a cleaner community where I don't have to deal with trolls all day - of if a troll joins, I make a quick $50 and they are gone!

So for that reason, I don't see an "in between" option.

 

1 hour ago, kicken said:

 Registered users are easier to track and  manage than a bunch of anonymous people.  If you ever want to do something like sell ads or potentially the website as a whole having statistics about usage will be very beneficial and registered users can give you some good statistics. 

True, but I hope to make the free part so enticing, plus the level-of-entry so low (i.e. "Hey, this isn't a lot of money, I think I'll give it a try!"), that people will quickly subscribe, but time will tell...

 

@kicken,

Since it sounds like my approach is okay to you so for (i.e. I allow people to have accounts without an active subscription), then what is the best way to handle the following scenario...

A first-time user of my site - after surfing around for free for a while - decides to purchase an annual subscription for $50.

During checkout, they Step 1: Enter Account Details, Step 2: Sign TOS, and Step 3: Enter Payment Details then click "Process payment".

My code successfully creates "Member", "TOS", "Order" and "Order Details" records in the database, but the payment processor sends back a "Fail" message because they didn't have enough available credit.

As the website owner, only 1 of 3 things got completed that I need completed (i.e. Member was created).  

I also need them to pay me, and I need them to "activate" their account by clicking on a link that I will send them.  (Standard procedure.)

So what is the smoothest way to handle this interrupted checkout?

 

Scenario #1:

I don't tell them (immediately) that their payment failed.  Instead, I display, "Your account has been created.  Please check your email and click on the activation link to start using your account."  Then after they do that, THEN I point out that their payment failed and they will need to go to the "Store", choose a paid subscription plan, and try checking out again.

 

Scenario #2:

I display a message t the effect: "Oops! Your payment didn't go through.  Please log into your new account, and try purchasing a subscription again."  (After I get a payment, I can worry about reqiring them to activate their account.)

 

Scenario #3:

Maybe there is a less "disruptive' way to allow them to try checking out again?  I'm not really sure from a UI/UX standpoint what is the most gracious way to handle this scenario...  🤔

 

 

54 minutes ago, SaranacLake said:

Scenario #1:

I don't tell them (immediately) that their payment failed.

Unacceptable.

54 minutes ago, SaranacLake said:

Scenario #2:

I display a message t the effect: "Oops! Your payment didn't go through.  Please log into your new account, and try purchasing a subscription again."  (After I get a payment, I can worry about reqiring them to activate their account.)

If you were able to create the account then log them in right then and there. Automatically. That voids this scenario.

55 minutes ago, SaranacLake said:

Scenario #3:

Maybe there is a less "disruptive' way to allow them to try checking out again?  I'm not really sure from a UI/UX standpoint what is the most gracious way to handle this scenario...  🤔

Multiple steps.

First step is to sign up. That has its own page. You can deal with duplicate emails and password requirements and even confirmation emails at that moment. Stop checkout until this is done.
That should also include your second "step" of accepting the TOS. If they do not accept then they should not have an account. In other words, a little checkbox "[ ] I accept the Terms of Service" that's required.

Then they are logged in and continue to the purchase step.

1 minute ago, requinix said:

If you were able to create the account then log them in right then and there. Automatically. That voids this scenario.

The *new* user enters in a username, email and password and enters payment details, clicks "Process order" and the payment fails.

How would I securely log them back in?  (I don't think there is such a thing - log in needs to always be done by the user!)

I could display an error message, "Oops! Your payment was declined.  <<Cancel>> <<Try again>>"

If they click <<Try again>>, I could reload the Checkout form, and use session data to populate the form MINUS the password and payment details, and make them try and checkout again.

 

 

1 minute ago, requinix said:

Multiple steps.

First step is to sign up. That has its own page. You can deal with duplicate emails and password requirements and even confirmation emails at that moment. Stop checkout until this is done.
That should also include your second "step" of accepting the TOS. If they do not accept then they should not have an account. In other words, a little checkbox "[ ] I accept the Terms of Service" that's required.

Then they are logged in and continue to the purchase step.

Again, after extensive research, all of the experts say that is an outdated approach that will lose you business, because people are impatient.

Remember: I am talking about *new* customers here (i.e. registering and checking out for first time).

if you are an existing Member, then the flow follows a more traditional e-commerce approach: Login, shop, purchase.

And now maybe you see why the easiest option for *new* customers who have a failed Checkout, is to simply roll back everything, and make them try again.  Although as I mentioned above, I could certainly try and make that easier by auto-populating as many fields as possible minus things like password and payment details.

I guess I haven't really paid attention or had this happen, but if I went to a site that sold subscriptions and the checkout failed, I am 95% certain I'd have to start all over since they don't have an account on file for me...

14 minutes ago, SaranacLake said:

Again, after extensive research, all of the experts say that is an outdated approach that will lose you business, because people are impatient.

I'm done. Do whatever you want.

10 minutes ago, gw1500se said:

Excuse me but "all of the experts?" Bull$hit. Requinix IS an expert as well as Kicken. You would be foolish not to heed their advice and it sounds like you will be foolish.

Being a guru on PHP does not make one an expert on UI/UX.

When you, or anyone else, has extensive *published* research on the topic of optimizing e-commerce checkout, then you can talk smack.  Until then, stick with PHP.

Sorry, I'll trust what industry experts with published research/journals/books over a single person's opinion.

And on this particular topic, requiring a new customer to first sign up for an account, and then activate the account, and then come back and browse your account and hopefully checkout is a guaranteed way to lose a significant amount of your customers.

Of course, that isn't what this thread is about, so please take your hostility elsewhere.

 

 

7 hours ago, SaranacLake said:

How would I securely log them back in?  (I don't think there is such a thing - log in needs to always be done by the user!)

You just do whatever you need to do to log them in as part of the member creation step.  There's no need to make the user go through some login process.

$userId = createMemberRecord();
$_SESSION['activeUser'] = $userId;

After that, create your order and process the payment.

7 hours ago, SaranacLake said:

and the payment fails

Every member on your site should have some sort of page they can access that will show them their order/payment history and allow them to update their payment details / change subscription.

If the payment fails, you send them to that page with an appropriate error message and a form to re-enter their payment details.

 

29 minutes ago, kicken said:

Every member on your site should have some sort of page they can access that will show them their order/payment history and allow them to update their payment details / change subscription.

If the payment fails, you send them to that page with an appropriate error message and a form to re-enter their payment details.

Yes, for existing members that is true.

I guess one of the earlier topics of debate is whether I should do that for a new member.

I am still kicking - no pun intended! - things around, and sketching things out and doing use-cases which help me to formulate a 20,000 foot view.

But as of now, it makes more sense to me to wrap up account creation and payment processing into a single transaction.  If they both succeed then the new member is on his/her way.  And if things fail - more likely the payment - then I will simply route them back to the Checkout page and auto-populate non-PII fields to help them out.

t complicates things more than it's worth creating an account for a new member without the payment in hand because of things like "Trial Offers".  You can't get a trial offer (e.g. 30 days for $1) if you are a member, and I don't want to have to write a bunch of logic to check if a Member is not yet really a member because their payment puked.  (It's a judgment call.)

But I'm still kicking - there's that word again?! - the tires.  😉

 

Hey Saranac,

You seem to be conflating a "transaction" which is a database specific term, with a single page application (SPA) or combined form.  What you do serverside with that form is up to you.

Ease of use, credit card/payment processing and the dangers and cost of fraud are a complicated witches brew of risk/reward calculations.  First of all, I don't know what you know or don't know about payment processing, but just because you got a cc authorization doesn't mean you will ever get paid.  Worse yet, you could get a chargeback, and if you have enough chargebacks, you might end up having your merchant account closed.  Again, maybe you know this or you don't.  I don't know what your content is, or whether or not there will be a high amount of fraudulent activity, but every online business has some.

So, as to transactions, and to "best practices" for selling digital goods or memberships, these topics are unrelated.   At its simplest,  a Member in your system, as you stated yourself, is not equivalent to a membership package.  Membership packages also have one or more related "entitlements".  So no doubt you have a package described in the database somewhere, and when someone successfully subscribes to a package for a year, one would expect a database structure like this:

package  ---<  member_package  >-- member

where member_package is a table that stores "member_id", "package_id", "from_date", "to_date".

What are strategies for dealing with the system.  Well one, would be to have the culmination of a successful payment process be the setting of the "from_date" and "to_date".  

Another strategy might be to also utilize a "status"  column with mutually exclusive states like: 

  1. pending payment
  2. active
  3. suspended for fraud
  4. expired

In that case you create the row, and can then use "active" status to drive access (along with from/to).  

Regardless of the form you use, there is no benefit to wrapping the creation of a member row with the transaction processing.   If a member fills out all their details and has payment processing issues, it behooves you to create the membership row and put them into "pending payment" state.  This way you can see how many people had issues with payment processing at any particular period of time.  That way you can reach out to people who for whatever reason drop out of the payment process.  You have contact info to market to them, or entice them with discounts.  And there is always the situation where your payment processor was rejecting everything and these are customers you have 100% lost forever without some record that they tried to subscribe.

DB transactions are important from a mechanical standpoint and I highly recommend using them, but you can have multiple transactions in your processing ie (membership account + address) THEN (payment processing & activation) and these can be handled separately in your code.  

Once you have some identity information, it's valuable to continue to carry this along in your session rather than stubbornly demand that the behavior of your system should conform to your ideal "happy path" scenario where a user puts in all their identity information for their membership perfectly, and at the same time gets the payment information entered perfectly and receives authorization.   A "member" row, should be decoupled from membership (which you already stated you understand and agree with) which should be decoupled from subscription(s) which should be decoupled from payment processing details.  

 

 

  • Like 1

@gizmola,

Thanks for the thoughts.  All of this is definitely a journey, because as I sketch things out (and talk to people) I learn new things and that can change my design.

Dealing with the unknown and not knowing how to design things until you successfully design thing is what makes all of this a challenge!

I'll take what you and others have said above and try to come up with a design that is flexible, scalable, and that helps me retain customers and make $$$.

Thanks.

  • Like 1
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.