OpenCart subscription model (x months) - php

I am setting up an e-commerce site using OpenCart and I want to offer subscriptions. Specifically 3/6/12 months subscriptions. I am NOT interested in recurring billing (I am aware that there are modules for PayPal and Authorize.net). I want users to pay once in advance. Does this translate to 3 pseudo-products from a configuration point of view? I guess this is feasible, so far, just with product configuration. 3 products, each with one price.
Here comes the tricky part. For every month the users have paid they have access to order a product, only once a month, within their "billing cycle". So, if a user pays for a 3 month subscription on 23/5:
he can get one product in the period 23/5-22/6,
one in 23/6-22/7, and
one in 23/7-22/8
A user should not be able to order more than one products per month, and he should not also be able to get any products after 22/8, unless he renews his subscription. Moreover, it would be awesome if I could have a cron job, checking if a user has utilized his subscription for the current month, and send a "Hey, get your product for this month" kind of reminder email.
This is my first OpenCart project, I have gone through the documentation and Googled a lot, I have played with a local installation, and I am trying to figure out if what I am asking is feasible without modifying the core code, I would like to avoid that. However, if there is no other way, I understand that OpenCart is an MVC(+L(anguage)) framework, but I haven't found any solid documentation on how to customize its functionality, only bit ans pieces for specific requirements.
If I may, I would like to write down, what I have in mind, please, advise if this sounds OK:
I would like to add one more entity (object/model) for storing the
subscription, the user to which it belongs, start and end date and
whether it has been utilized. Basically, a subscription is a normal
order and I would like it to be stored like one, I just need to
persist a few more fields. As I said, I need to run two checks:
Has the user utilized his subscription for the current month? For
this I was thinking about having a flag "isUsed" field, which can be
reset with a cron job, everytime a user reaches his billing date. (in
our example 23/6, 23/7). Alternatively I could add 3 entries, one for
each billing cycle and update them accordingly.
Has the subscription expired? I could check against the expiry date
of the subscription.
I have no idea how to plug this functionality in, during checkout, or how to start implementing this.
I have gone through the forum and Googled heavily, but I didn't find an answer yet. I am an experienced Grails/Java EE developer, so I am pretty technical in case this post gets too techie :-)
Does the above sound feasible, and am I on the right track?
Cheers,
Iraklis

This functionality is way outside what Opencart is built for, but if you have some familiarity with PHP/CodeIgniter then you should be able to do most/all of the mods. SQL will be good to know as well, but if you don't already it is fast to learn.
I would say your mods come in 2 parts each with it's own level of difficulty.
I am setting up an e-commerce site using OpenCart and I want to offer
subscriptions. Specifically 3/6/12 months subscriptions. I am NOT
interested in recurring billing (I am aware that there are modules for
PayPal and Authorize.net). I want users to pay once in advance. Does
this translate to 3 pseudo-products from a configuration point of
view? I guess this is feasible, so far, just with product
configuration. 3 products, each with one price.
Here comes the tricky part. For every month the users have paid they
have access to order a product, only once a month, within their
"billing cycle". So, if a user pays for a 3 month subscription on
23/5:
he can get one product in the period 23/5-22/6,
one in 23/6-22/7, and
one in 23/7-22/8
I think what I would do for this is add a product for each subscription length, and each product with issue them the appropriate account credit, and have this credit the perfect amount to buy one product per month for the subscription length.
To do this I recommend adding a function to add the funds into the customer_transaction field in the database in the file catalog>model>checkout>order.php (or any model you choose) then call it and add data in catalog>controller>checkout>success.php.
I think it would be smart to verify that the customer has purchased the appropriate subscription product and to verify that there has not been a credit for that purchase already.
To ensure they get only 1 product per month you will need to write a script to the beginning of catalog>controller>checkout>checkout.php to redirect them to an error message if they try to get products too often.
A user should not be able to order more than one products per month,
and he should not also be able to get any products after 22/8, unless
he renews his subscription. Moreover, it would be awesome if I could
have a cron job, checking if a user has utilized his subscription for
the current month, and send a "Hey, get your product for this month"
kind of reminder email.
I don't even know where to start on this one, but if you are willing to pay you could post for help and probably add this function for a good price.
This is my first OpenCart project, I have gone through the
documentation and Googled a lot, I have played with a local
installation, and I am trying to figure out if what I am asking is
feasible without modifying the core code, I would like to avoid that.
However, if there is no other way, I understand that OpenCart is an
MVC(+L(anguage)) framework, but I haven't found any solid
documentation on how to customize its functionality, only bit ans
pieces for specific requirements.
Again, this is way outside of what Opencart is built to do and will take several modifications. As for documentation on how to Opencart scripting works and how to customize it, I haven't found any either. It's been quite a struggle for me to learn what I have over the last 2 months, but if your questions are short you can usually get people to help you along the way when you need it.
If I may, I would like to write down, what I have in mind, please,
advise if this sounds OK:
I would like to add one more entity (object/model) for storing the subscription, the user to which it belongs, start and end date and
whether it has been utilized. Basically, a subscription is a normal
order and I would like it to be stored like one, I just need to
persist a few more fields.
I would add these as attributes, you can do this in the administration on the back end of the website catalog>attributes, catalog>attribute groups, and catalog>products in the attributes tab.
As I said, I need to run two checks:
Has the user utilized his subscription for the current month? For this I was thinking about having a flag "isUsed" field, which can be
reset with a cron job, everytime a user reaches his billing date. (in
our example 23/6, 23/7). Alternatively I could add 3 entries, one for
each billing cycle and update them accordingly.
Has the subscription expired? I could check against the expiry date of the subscription.
I don't know how to do this cron job but if you can figure that out you could search the database for the attribute name(s) and values then apply your cron job if the values are within your range.
Hope this helps you with your expectations!
UPDATE
To insert data into the database you could replicate something like the addTransaction () function in the admin/model/sale/customer.php
public function addTransaction($customer_id, $description = '', $amount = '', $order_id = 0) {
$customer_info = $this->getCustomer($customer_id);
if ($customer_info) {
$this->db->query("INSERT INTO " . DB_PREFIX . "customer_transaction
SET customer_id = '" . (int)$customer_id . "',
order_id = '" . (int)$order_id . "',
description = '" . $this->db->escape($description) . "',
amount = '" . (float)$amount . "',
date_added = NOW()");
}
And this in admin/controller/sale/customer.php
$this->load->model('sale/customer');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->user->hasPermission('modify', 'sale/customer')) {
$this->model_sale_customer->addTransaction($this->request->get['customer_id'],
$this->request->post['description'], $this->request->post['amount']);
$this->data['success'] = $this->language->get('text_success');
} else {
$this->data['success'] = '';
}

Related

In Laravel, how do I know what a customer is currently being billed?

I'm using Laravel 5 with the Cashier package. I have some simple subscriptions ('standard' and 'pro') set up.
I need to show how much the user is currently being billed per year - the subscriptions are both annual.
I also have a handful of coupons a user can use. So, how can I show what the user is currently being billed, taking into account their coupon they may or may not have used?
I'd like to think $user->currentBillingPrice might exist, or something similar. I'd even be happy with $user->invoice->latest->total, if such a thing exists?
For those still looking for this answer.
You have access to the Stripe objects which contain the information you're looking for. Here is an example of how to get this information for percentage coupons.
To get subscription information (change 'main' to what you use)...
$sub = $user->subscription('main')->asStripeSubscription();
$plan = $sub->plan;
$amount = $plan->amount;
$percent_off = $sub->discount->coupon->percent_off;
To get user information (you can apply a coupon to the user and it applies to all his invoices)
$stripe_user = $user->asStripeUser();
$percent_off = $stripe_user->discount->coupon->percent_off;
In case someone comes looking for this still, as it's pretty high in search results, "asStripeUser" appears to be "asStripeCustomer" now. You can use it to grab a plethora of information about the current customer.
$info = $user->asStripeCustomer();

Authorize.net - ARB - enabling/disabling subscription

So I am dealing with Authorize.net's ARB, and I have a situation where the user is applying for usage of our service for eg. 3 months. We charge the user for this period - 3 months, but we don't make a subscription immediately. The thing is, we don't want to automatically charge them again once the membership expires after 3 months, but only if they go to account settings and set that option (extend membership automatically). So if they don't select it, there is no need to establish a subscription, so that's why we aren't doing it in starting point, once the user applies for this service.
So the question is, should I create a new subscription once user selects "Yes" for that option, and delete the subscription when he selects "No" ?
Is there another way to do it?
It's really hard to find some answers by Google, and I was hoping someone with more experience will have an answer here.
Thanks in advance.
When the user selects "Yes" for the new subscription just create a new ARB subscription with a start date of three months past their three month trial period. The three month subscription will run its normal course and terminate after three months. Then the new subscription will start at that point.
But here's the catch with that solution: you need the customer's credit card information in order to recreate another subscription. Unless you store it somewhere (bad idea) you can do that. So you would need to ask for it again. That's a large hurdle to overcome and will negatively affect conversion rates.
Alternatively you can automatically create the three month subscription at the point where the user starts their three month trial. As they approach the end of the three month trial you should make them aware there subscription will automatically start unless they cancel it. This solves the creation of the subscription problem but isn't very popular with users as nobody likes being automatically enrolled in a subscription.
Third option is to use Authorize.Net's CIM API to create a payment account for that user. Then you can charge against their card whenever you want. The problem with that is CIM does not support subscriptions. So you'd have to write your own subscription engine to make this work.
So there is no ideal solution for this. You just need to pick the one that you think works best for you.

Updating Stripe plan customer number in PHP / CodeIgniter

This is my first time interacting with Stripe and trying to tie it into CodeIgniter.
Currently, when you create an account on my application it adds you to the correct Stripe plan and increases the total amount to be billed on that account.
I'm having a problem trying to work with this subscription plan #. I found in their documentation that this deals with the Subscription plans quantity.
What I need to happen is when you deactivate a user, it needs to update the quantity to 1 less. I can't figure this out.
Playing around with their API I was able to completely delete a subscribed customer by doing:
$this->load->library( 'stripe' );
$this->stripe->customer_delete('cus_1WS0pth6srNf7H');
Now I'm working with:
$this->load->library( 'stripe' );
$customer_id = $company->stripe_id;
$this->stripe->customer_update($customer_id, **WHAT GOES HERE?**);
Any help would be greatly appreciated. To sum this up, I need to update the quantity of my plan to -1 when a user is deactivated. The user is being deactivated fine in my application, but now I need to send a request to Stripe to update my plan to 1 less user.
Perhaps the customer_update function isn't the right one to use for this? There are a lot in the Stripe.php file.
Once I have this solved I can handle applying it to reactivating a user.
Here is the documentation where I think I need to be
I've been using Jason Horwitz's fork of bcessa's php-stripe library. It appears to be kept up to date with Stripe API changes.
https://github.com/sekati/php-stripe
Anyways, this is what I did for applying a plan to a customer
$request = $this->stripe->customer_subscribe( $stripe_id, $plan );
According to Stripe's API Docs, this will prorate the difference (if changing from one plan to another) by default so if that's what you want, you're good. If not, you can add it to the options array like so:
$request = $this->stripe->customer_subscribe( $stripe_id, $plan, array('prorate' => false) );
Not clear if you are using this library or not, but you should check:
https://github.com/bcessa/php-stripe
Written for CI & very simple. I'm going to assume you are.
According to Stripe support (I did this exact same thing recently), you need to actually make a unsubscribe & resubscribe to a new plan.
The steps I want through, roughly, were:
1) Get next invoice - so I could capture the next billing date for the new subscription (we used a trial period, so I needed this. you might be able to skip)
2) Unsubscribe the customer
3) Get my new total user count
4) Create a plan id (can be the same as you had before, I believe)
5) Subscribe with the new count to the new plan
6) Update anything on your own db

PayPal Modify Subscription - Payment Standard

So I've implemented PayPal fully into my system. The system works on user 'packages', all at set prices. Each user has a subscr_id (set by PayPal) assigned to them, along with details of the package they've bought.
I need to be able to modify the subscription so the user can select a different package. Essentially I just need to be able to change the amount and the 'custom' field (this contains package details, coupons used, etc).
I would have thought, and hoped, that it would be as simple as showing the user another form with hidden fields for 'modify', 'subscr_id', 'custom' (new value) and 'amount' (new value). Unfortunately I can't find this anywhere online, and PayPal's documentation is so monolithic that I find myself going round in circles for hours at a time.
My IPN is all set up and working fine, I literally just need to build a form that allows me to set the 'amount' and 'custom' variables to something new... the bit I thought would be easy! Any help is greatly appreciated. Thanks in advance.
I've been looking into this recently. You can create a "Modify Subscription" button to change subscription details such as amount and period. When the user clicks this button, they login and see the old subscription details and the new subscription details, and must approve/save it for it to take effect. One major issue though is you can only increase the subscription amount by 20% within a 10-day period.
To create the modify subscription button just use the regular subscription HTML button with the new parameters you want, and add an extra parameter "modify=2" (2=modify only, 1=modify or sign up).
Also I think that the custom variable field does not change even if you modify the subscription, but I am not 100% sure on that.
After a wee bit of searching, hopefully this will help:
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_subscribe_buttons#id09A7G0502UI
If you became a PayPal Merchant after October 15, 2009, you can edit a buyer’s subscription profile.
As a subscription service provider, you can edit a buyer’s subscription profile in the Edit Profile page. Use this page to update buyer information, adjust the cost or cycles of the subscription, and specify how to handle missing or failed payments.

Dealing with two people buying a unique item in an online shop at the same time

I'm creating a simple online shop with PHP integrated with PayPal that sells unique items. What I'm wondering is how other shops deal with multiple people attempting to go through the payment process with the same item.
This is my current draft strategy:
Items have three status types: available, on hold & sold.
As a user moves to the PayPal payment page it checks the status of all the items in the cart to ensure they're available. It also sets the item's status to "on hold" until they either come back after payment is confirmed or it times out (10 minutes? Not sure what this should be).
Is this standard practice or is there a more practical way I should be going about this?
Thanks in advance!
Have a look at Dell's UK outlet. When someone adds a system to their shopping basket it is held and not available to other customers. If it isn't purchased, the item is removed from the basket after 15mins of inactivity and is then available to other customers.
I would say the first part of your strategy is correct - as you move to the payment page, flag all the products as 'on hold'
When the user has finished the payment, you will get a postback from Paypal which lets you know if the authorisation was successful or not (and possibly also allows you to check the CSC/CVV2 result), and at that point you have the option of either accepting the payment, or rejecting it.
On receipt of the postback you should also check whether the items are still on hold. If they have timed out you can reject the payment and display a message 'sorry - timeout exceeded' or somesuch.
This method also allows you to work out an ideal timeout period if you keep track of how often customers run into the timeout, so you can extend the timeout from (eg) 5 to 10 minutes if too many are timing out, or shorten it if none are timing out.
This is a fairly common issue with fixed inventory systems such as venue, transport/airline tix etc.
I like the airline model where once you get the itinery you want and click select, you get a page with passenger info with a message saying, seats on hold and you now have xx(10/15) minutes to complete the purchase. Everything becomes explicit at that time. For other unique/one of a kind item, I'd think a message on any page, that the user clicks on, saying you have xx(mins) remaining to complete the purchase would be a big motivator for "on the edge" buyers !
woot.com is notorious for this problem but their solution works well. After payment information is verified the user is brought to a page with a small amount of text saying something like "your order is in, we are verifying inventory".
It looks like the paypal API has a "RefundTransaction" message so something like that might not be possible. But the user experience could be awkward if your going to the paypal website then coming back to your site.
This is much like booking theatre tickets or similar online and yes the way you describe is generally the way it works. At some point the item is "reserved" in the system and either the customer completes the transaction or the item is released after some time for others to buy.
Of course at what point you reserve the item (when it's added to the cart, at the point you send them off to pay etc) is up to you. I would expect putting it in the cart would be the best choice as it makes it less likely someone will build up a basket of stuff only to find half of it is no longer available at the checkout.

Categories