Posts Tagged ‘checkout’
07
Jul

If, you get a message like this:  “Please enter a valid credit card verification number.” every time you enable “CVV check” in your payment gateway, and you are sure that your payment module settings are correct and your card details are valid then, its most likely that the message is not coming from your payment module.

Instead it could be that the control is not reaching the payment module at all and the message is coming from this Magento file:
app/code/core/Mage/Payment/Model/Method/Cc.php line #150, validate credit card verification number section.

Why is this happening? Does this error occur for ‘Saved CC’ payment method too (it is the default card payment method got with Magento)?

Well, one reason that I found is – custom checkout module. Are you using any custom checkout module? If yes, then disable it and try the normal Magento one page checkout. The chances are all will work fine. I have noticed that some custom checkout modules fail to send the CVV number back to the code – hence, Magento will catch it and throw back the error – the payment module is nowhere in the picture yet.

So, before you panic that your card details are invalid or your Payment Gateway or payment module is not working, confirm that it is not your custom checkout module that is the culprit.

, , , , , , , , , , , , , , , ,

24
Feb

You need to have a set of global variables and functions that can be accessed through all classes – how do you do it in Objective C?

Objective C doesn’t understand the concept of global functions or variables as such – you need to go the objective programing way to simulate global functionality.

There are 2 solutions for this:

  1. Use the AppDelete class
  2. Create your own singleton class

Basically, both the solutions are the same since the AppDelegate class is also a singleton class.

Here, I will explain solution #2 (its not good programing practice to write business logic in the AppDelegate)

First, what is a singleton class? A class that can have ONLY one instance throughout the program is called a singleton class. It means, if you have created an object of a singleton class, when you try to create a new object it will not create it! Instead it will return the reference of the first object.

We can use this feature to simulate global functionality – there can be only one instance of this class hence, the properties and methods defined in the class can be accessed across classes without any change in values.

For, a more detailed explanation you can checkout this wiki link: http://en.wikipedia.org/wiki/Singleton_pattern

Now, lets get to the actual code. I assume you already know how to create a project in XCode and have a simple project ready.

Step 1: Open your XCode project and add a new class.

In your XCode > ‘Group & Files’ colum > Right click on the classes folder > Click ‘Add > New File..’ > Select ‘Objective-C class’ (ensure its a sub class of NSObject) > Click ‘Next’ > Enter the new class name (in this example, GlobalData) > Finish

Step 2: The .h file

This is the interface file

@interface GlobalData : NSObject {
NSString *message; // global variable
}

@property (nonatomic, retain) NSString *message;

+ (GlobalData*)sharedGlobalData;

// global function
- (void) myFunc;

@end

Step 3: The .m file

This is the implementation file

#import "GlobalData.h"

@implementation GlobalData
@synthesize message;
static GlobalData *sharedGlobalData = nil;

+ (GlobalData*)sharedGlobalData {
    if (sharedGlobalData == nil) {
        sharedGlobalData = [[super allocWithZone:NULL] init];

	// initialize your variables here
	sharedGlobalData.message = @"Default Global Message";
    }
    return sharedGlobalData;
}

+ (id)allocWithZone:(NSZone *)zone {
	@synchronized(self)
	{
		if (sharedGlobalData == nil)
		{
			sharedGlobalData = [super allocWithZone:zone];
			return sharedGlobalData;
		}
	}
	return nil;
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (NSUInteger)retainCount {
    return NSUIntegerMax;  //denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}

// this is my global function
- (void)myFunc {
	self.message = @"Some Random Text";
}
@end

Step 4: How to use it

In the implementation file of the class where you want to use the global variable or function include the GlobalData.h file

#import "GlobalData.h"

To access the global variable (that is the singleton class property) do this:

[GlobalData sharedGlobalData].message

GlobalData is our class name, sharedGlobalData is a class method which will check if there is already an instance for this class – if so, it will return that else, it will create a new instance and return it. “message” is the name of our class property – which we are going to use as a global variable

To access the global function (that is the singleton class method) do this:

[[GlobalData sharedGlobalData] myFunc];

Just like before, we get the singleton object and then call its method – which we are going to use as a global function.

In this way you can include the GlobalData.h file in any number of classes and use the variables and functions – the variable values will be shared between all the classes.

Hope you find this useful…let me know your feedback!

Reference links:

http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/Singleton.html

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html%23//apple_ref/doc/uid/TP40002974-CH4-SW32

, , , , , , , , , , , , , , , , , , , , ,

06
Dec

EDIT: This article is applicable for Magento versions 1.5.0.1 too

The latest 1.4.x series of Magento has some small changes/enhancements which are not exactly backward compatible. This is especially true with themes.

As payment module developers, we get a lot of people coming back saying that after upgrade or fresh installation of the latest version, the payment step on the one page checkout doesn’t work.

If, you have a custom theme installed and, after upgrade, you find that your checkout is not working – that is after entering your credit card information and click ‘Next’ nothing happens – follow these steps: More »

, , , , , , , , , , , , , , ,

24
May

Got this nice extension which puts a ‘Newsletter Sign-up’ check-box on the Magento checkout page.

http://www.magentocommerce.com/magento-connect/QuickModules/extension/1361/checkout-newsletter/

Due to permission restrictions I was not able to connect to the Magento Connect Manager link on my live cart. So I went ahead and installed it on my localhost Magento. Here are the steps:

1. Login into Admin > Magento Connect > Magento Connect Manager
2. Re-entered the admin username/password
3. Enter the extension key I got from the URL above
4. Click “Install”
Configure the module
This is a simple (and extremely useful) module with not much configuration needed.
To enable and configure the module I went to Admin > System > Configuration > Customer > Newsletter
Here I saw a new section ‘Checkout Newsletter’. This is my settings:
Enable => yes
Checked by default => yes
Visible to guest => yes
Visible to registrant => yes
Now when you checkout you will see a check-box to sign-up for newsletter.
How to shift this module to your live cart?
Since, I couldn’t use the Magento Connect Manager on my live cart I FTP-ed these files:
(The name of the module is checkoutnewsletter and the company that created it is Desitex)
1. Copy the file Desitex_Checkoutnewsletter.xml from the app/etc/modules folder
2. Copy the folder Desitex from app/code/community folder
3. Copy the folder checkoutnewsletter from the app/design/frontend/default/default/template folder
4. Copy the file checkoutnewsletter.xml  from the app/design/frontend/default/default/layout folder
5. Login into the admin area and clear the cache.
To configure the module, follow the same steps as for the localhost cart.
Thats it!
[Edit]
Thanks to Brady, I took a closer look at the module. The module will break for Magento ver 1.4 beta1 and above – here is the fix:
Open the file:
[magento-root]/app/code/community/Desitex/Checkoutnewsletter/Model/Observer.php
On line number 10 change:
case Mage_Sales_Model_Quote::CHECKOUT_METHOD_REGISTER:
to
case ‘register’:
On line number 14 change:
case Mage_Sales_Model_Quote::CHECKOUT_METHOD_GUEST:
to
case ‘guest’:
The use of these 2 constants became deprecated since Magento 1.4 beta1

, , ,

26
May

For understanding controllers we need to know how the Magento processes requests from the browser. Look at the following diagram which shows the page request flow. This diagram will give you an idea of the job of controllers.

page-request-flow

Job of the controller:

The controller receives a URL request from the browser. The controller has to process this request to find what code to run. This is done via a router. Routing is the process of taking a URL and decomposing it into parameters to determine which module, controller, and action of that controller should receive the request. The URL gets “routed” to a particular Controller, which in turns tells Magento what to do. The Controller tells Magento which layout is to be used. This determines which modules are put into place, which in turn tells Magento what Views to output. The data from the Models are given to the Views to be displayed. In the scheme of things here, Blocks fit roughly between the View and the Model.

Decomposing the URL:

Now we will see how a browser request to a URL gets translated into module execution. Generally speaking any URL can be deconstructed as follows:

decomposeurl

As you can see the above URL has been decomposed to get the module as ‘customer’, the controller as ‘AccountController’ and the action to be performed as ‘indexAction()’. Checkout the AccountController file in Mage\Customer\controllers\ . You will see an indexAction() function. This is the function that is executed by the above URL request.

indexAction

If the URL was http://example.com/magento/(index.php)/customer/account/login then the loginAction() will be executed.

So The front controller (the controller that receives requests from browser) “dispatches” the request to its internal list of “routers” and determines if any of the routers “match()” the request’s parameters. If so, then a new MVC Controller (‘AccountController’ in this case) is created from the matching module and, again, the request is “dispatched” to this controller object. The final MVC-style controller is technically a “Front Action” (Notice that AccountController extends Mage_Core_Controller_Front_Action).This new Action object dynamically calls one of its own action methods (‘indexAction()’) and marks the request as being “dispatched” (i.e. finished).

How the routers find a match?

The front controller has an array of “routers” that it uses to decide which module the URL should trigger. This correlation between URL and module name is defined in the config.xml files of the modules. Checkout the config.xml file of the Customer module you will see this:

customerrouterxml

Once a router has found a match of the first part of the URL to a defined frontName value from the XML, this value gets directly translated into a module name with a little adjustment to the capitalization of the words (ie. ‘customer’ to ‘Customer’) The controller and the action names are taken from the URL.

What if you only enter example.com/customer/ and not specify the controller and action you want. Find out what result you get. You will be directed to the 404 Not Found error page. How did that happen? If any value is missing, the defaults are taken from the config.xml of the Core module. If any indicators of module, controller, or action are missing from the URL the values are read from the default tag under web. By default, the CMS supplies these XML values it its own config.xml file. You can change these values by going to System->Configuration->Web.

defaultroute

Actions:

Actions are classes that extend Mage_Core_Controller_Front_Action which, in turn, extends Mage_Core_Controller_Varien_Action.(‘AccountController’ is an Action). A request is dispatched to an action method (‘indexAction()’). Action methods have the word “Action” appended to their names to distinguish them from normal class methods. Appending a word to the method name also helps to stop people from running unexpected methods from the URL. Imagine someone requesting example.com/index.php/customer/account/__destruct. If the system did not protect action names, the resulting method call would look something like this:

$controllerInstance->__destruct();

Something like this could potentially be a vector to open up attacks on your site. So Magento protects the action method names by appending Action to any value taken from the URL. Action and action methods are where the primary business logic for a request happens. Typically the action methods will load a model or two based on IDs or other URL parameters, kick off a few methods of these models, and then run the layout sequence.

Launch your browser and type http://127.0.0.1/magento/index.php/customer/account/login/. This should execute the loginAction() method in AccountController class of Customer module.

The Output will be as follows:

login

, , , , , , , , , , , , ,

05
Jan

Steps to enable or disable terms and conditions for checkout Login as admin and select System->Configuration, Click on "Checkout" under SALES, then click on Checkout Options. Then select Yes to enable terms and condition and No to disable terms and condition from Enable Terms and Conditions drop down and click on Save config button.

, ,