Author Archive

So You Want To Build A Software Product





 



 


If you like the idea of being your own boss (I certainly do), chances are you get the itch sometimes to create your own product — a product whose direction you control, that you do not have to compromise on with someone else, and whose fruits you get to fully enjoy, instead of being paid by the hour or a flat rate. It could be a Web service, a WordPress plugin or a desktop application, but the core problem is the same: how do you pick an idea that will succeed?

Most of us take a very simple approach: we stumble on something that doesn’t work well for us or we identify a problem that we have a lot of experience with, and we think, “All right, I’ll just build x for y and make a mint.� The problem is that we don’t have any indicators of whether others feel the same pain and would be inclined to pay for a solution.

This post presents a systematic approach to finding inspiration for a good software product, and to validating that there is an actual need for it in the real world. No product is guaranteed to succeed, yet our goal should be to minimize risk and maximize opportunity by picking the ideas that will most likely succeed.

(Please note: this article concerns developing commercial ideas. If you want to build an open-source project and do not care about commercialization, then it might be less relevant to you.)

Finding A Good Idea For A Software Product

Some of us develop a product after naturally coming up with the idea while performing a certain task. But what if you want to start your own venture but don’t yet have an idea of what to build? How do you find inspiration for a new software product?

Community Websites

A great source of inspiration is community websites, such as Q&A platforms, forums and social networks such as Facebook and Twitter, where your target audience hangs out. Want to build a WordPress plugin? Visit a forum for professional bloggers. Want to build productivity software? Visit a LinkedIn group for the professionals you want to target. Searching on Twitter for your preferred platform or product type can be an amazing source of inspiration.

Find out where your potential audience hangs out and soak up the atmosphere. Read about people’s problems and pains with their current software. Pick up hints on what would make their lives easier (or, in the case of games, what would entertain them most). Search for things that most of the community agrees on, and try to develop it into a concrete concept.

Don’t expect an idea to be handed to you on a silver platter. Rather, get a feel for what your target audience needs, and from there build a concept. (We’ll go over how to figure out the potential of that concept in a bit.)

Variation of a Successful Product

Successful products have the advantage of a proven concept. Many other factors come into play, of course, such as execution, marketing and timing, but a successful product already at least has traction and a user base that you can target right away, increasing your chances of success.


(Image: Viktor Hertz)

I’m not suggesting that you simply clone an existing idea. That could work, but competing with an established product with a mere clone would likely result in failure (unless other factors were involved); and, frankly, cloning an existing product isn’t much fun. You could, however, attack a weakness in another product, turning it into a strength in yours and creating an attractive variation that feeds on the popularity of the original product.

Playing to Your Strengths

Each of us has experience with certain tools, frameworks, APIs and projects. Go over your old projects and library of code, and think of how to build on that experience to create something new. This is how I created my own product, Binpress, a discovery service and marketplace for source code.

Covering familiar ground by building on past experience instead of trying something completely new helps to eliminate some of the risk. Using old code libraries can save significant development time, thus reducing some financial risk. I’ve previously written about how to extract code from old projects, the benefits of which seem especially relevant when you’re trying to reduce risk in a new software venture.

Taking Notes for Later

You’ve probably had many small a-ha moments, when you identified a missing feature in a software product. I have those all the time, when I think “If only this had feature x� or “This junk just doesn’t do what it’s supposed to do.� Each discovery is an idea for a potential product.

Such ideas pop up and then disappear from our memory. If only we take note, one of these minor revelations could turn into an action item. It’s all about discipline. The next time you have such a thought, write it down somewhere you’ll find later. Going over these notes in a few weeks or months could lead to your next breakthrough.

Assessing The Market

By now you have a few product ideas. But how do you know which is your best bet? A few parameters will affect your choice of which idea to develop. And this information will be useful if you ever want investors to support your product financially.

Market Size and Addressable Market

The bigger the market, the higher the potential payoff. Because you will likely be putting in the same amount of effort and time regardless of market size, targeting a big market makes more sense.

The important metric here is total addressable market, which basically means the total amount of revenue you can expect to capture.

There are two common ways to calculate this number: top down and bottom up. In the top-down approach, you start with the total size of the market, and then filter down to your target audience. For example, you could start with the total amount of revenue generated for online t-shirt sales, and then multiply it by the fraction of the market that you intend to capture (let’s say, biker-themed t-shirts).

In the bottom-up approach, you calculate the addressable market size by developing a formula that calculates profit based on your business model. For example, if your model is subscription-based, then multiplying the amount that you intend to charge by the number of people in your target audience will give you your total addressable market.

This is, of course, a simplification of the process. The complexity of measuring the total addressable market will depend on the market in question and the information available for it. You might want to read “Addressable Market: Making the Estimate� by Mark Peters Davis and “Market Sizing: Numerical Narratives� by Jay Haynes.

Actual and Potential Demand

Total addressable market represents the revenue that your product can capture. But will people actually pay for it? To answer this question, more research and thinking is involved.

Search Engines
You wouldn’t believe how many ideas could have been dumped if people had just bothered to search for them. Think of several keywords that represent the problem you want to solve and run them through Google (or Bing, whichever you fancy).

If more results are for people looking for a solution than for actual solutions to the problem, then you might have a winner. Run several variations of the queries based on the search results, until you have a good sense of what is publicly available when people search for a solution.

If you find little mention of the problem, then either your keywords are wrong or the problem is not as big as you think. This is not a game-breaker, but do take note. Some products create new markets or change established ones by generating demand. The demand for such products is harder to assess through a search engine and requires that you trust your vision and instincts, if you decide to follow through.

Staking Out Your Audience
We mentioned community websites in the idea-searching phase, and your research there might tell you what the community thinks. If not, now would be a good time to read what people are saying about the problem. Relevant discussions in online communities could be a great resource for validating and improving a product idea.

If you have experience in the market, then you might already know potential customers (online or off). In that case, you can get great feedback by approaching the ones you trust and asking them about your idea.


(Image: Viktor Hertz)

You might be protective of your idea and reluctant to share it with a relative stranger, but I recommend putting it out there as early as possible and getting real-world feedback. Feedback will help you determine whether the idea is worth pursuing and how to refine it. Steer clear of feedback from family and friends, because their opinions will obviously be biased.

Don’t let negative feedback get you down either; take it at face value. Remember, despite the old adage, the customer is not always right — otherwise, we’d be all riding faster horses instead of driving cars.

Your Personal Evaluation
Despite these methods, getting a sense of the demand might still be difficult, especially if you expect the product to generate new demand. In this case, you will have to rely more on your market experience and intuition.

It all boils down to, do you personally believe this idea is worth developing? From my experience as an entrepreneur, if you believe strongly enough that something can be a big success, then you will find a way to make it happen. It might not go as smoothly as you’d like, but as long as you keep believing, you will pull through eventually. Your personal belief in the potential of the idea should be the determining factor in developing it.

Check Out the Competition

You can learn a lot about the market by checking out the competition. Even if you don’t have direct competition, you will have indirect competition that competes for the attention and pocketbooks of your target audience. Not being able to find any competition at all is usually a sign that your idea is not commercially feasible — unless it is truly revolutionary (which is rarely the case). The existence of competition will validate your idea and could be a trove of inspiration and information on what works and what doesn’t.

Check out your competition’s websites, their mentions in traditional media (news websites and blogs) and their presence in social media. You will learn a lot about where they are as a business, what people think of them, their level of success, their main problems, people’s complaints about them and much more.

Are there major players in your market already? How entrenched are they? How hard would it be to compete against them? Competition provides both validation and a challenge, and it should factor heavily into your decision on whether to develop your idea.

In The End, It’s All You

Building your own venture might be a little intimidating, but it’s an amazing experience. Reducing the risk by doing research is an important first step. That being said, the most important factor is your belief in the potential of the product.

A strong belief in the product will help you get through difficult times, when development stalls or sales decline. It will be your shield against the doubters and haters — and if you gain any traction, you’re certain to get both.

To build your own business, you have to believe in your abilities and in the product. Everything will fall into place from there, and it will be one heck of a ride. Don’t be afraid to fail; make your best effort and learn from your mistakes. If you can tough out the bad times, the good times will arrive, and they will be worth it. Good luck!

(al) (il)


© Eran Galperin for Smashing Magazine, 2011.


You’re Pricing It Wrong: Software Pricing Demystified





 



 


Pricing your own product is always a tricky proposition, and the more critical the price is to your product’s success, the more difficult it is to set. It’s easy to look at another product and say how much you would be willing to pay for it, but how can you know how much people would be willing to pay for yours?

There are no absolute truths or perfect formulas for finding the best price, assuming that the “best price� even exists. Instead, take a structured approach to finding a good starting point, and improve it through feedback and testing. But first, you need to understand what the best price actually is.

Riding the Demand Curve

When we price a product, our goal (assuming we’re running a business) is to maximize revenue. We want sales × price = highest possible value.

Economic theory suggests that as we raise the price, the number of sales will drop. Each intersection of price and number of sales can be plotted on a graph, creating what is called a demand curve.

The sweet point is where the intersection forms the largest rectangle. This rectangle represents the calculation of sales × price, and the biggest rectangle represents the biggest revenue.

This makes sense… until you consider that your clients are people, and people do not often make rational purchasing decisions. In his excellent eBook Don’t Just Roll the Dice, Neil Davidson says (emphasis is mine):

Once you’ve determined what your product is, you need to consider its value to your customers. In the case of the Time Tracker 3000, let’s say that it will save a particular customer, Willhelm, three hours of work and that Willhelm prices his time at $50 an hour. That means that Willhelm should buy the Time Tracker 3000 at any price under $150, assuming he has nothing better to spend his money on.

Of course, this assumes that Willhelm is the rational, decision-making machine that economists love. In fact, Willhelm is a flesh-and-blood, irrational human being who doesn’t price his time and calculate costs and benefits. He has a perceived value of the Time Tracker 3000, which may or may not be linked to its objective value.

Neil goes into much more detail than I can in this article, but to recap quickly: perceived value can be different than objective value, and it can affect sales in ways that the demand curve does not predict. For example, when buying a brand-name product, you are intentionally paying a premium because the perceived value is higher, even if the objective value is the same. Some brands purposely price higher in order to increase the perceived value and thus sell more.

Pricing Higher And Selling More

Taking the fictional issue tracker in Neil’s book:

Back to Willhelm and the Time Tracker 3000. If you want to change how much Willhelm will pay for your product, then changing the product is one option, but only if you can also change his perception too. In fact, it turns out that you can change Willhelm’s perception of your product’s worth without touching the product at all. That’s one of the things marketing is for.

That’s right. You can set a higher price without changing your product just by changing the potential customer’s perception of the product. For example, you could increase perceived value by writing better marketing copy (focusing on the value that you’re providing or the pain that you’re solving). A killer demo can do wonders, as can strong testimonials and well-known partners.

One of the best ways to increase perceived value is to have better visual design — which, not surprisingly, is one the weakest links in marketing for most software developers. A well-known fruit company has become a giant by out-designing its competition, and it’s no coincidence: Apple charges a premium because of the perceived value of its products.

One common way to identify perceived value is to check the competition. Are you selling a WordPress plug-in for newsletter management? Google the keywords to see what else is on the market. If you’re in luck, you’ll be providing the only solution in this space. If not, you’ll have to consider that your clients can use Google just as well as you can and thus take your competitors’ pricing into account.

What do you do if a free product does what your product does? In this case, you have four options:

  1. Demonstrate that your product either is clearly superior or has features unique to it;
  2. Work on creating such differentiators;
  3. Win on marketing;
  4. Provide support.

Providing support is an important differentiator; one of people’s biggest deterrents from using a lesser-known free or cheap product is their concern about ongoing problems and future needs. A commercial product that comes with support will often win over customers who want that assurance that someone will be on the other end of the line should they need it.

Providing support has another benefit in addition to increasing the value of the product: it’s a chance to get real feedback! The feedback you get from support requests will enable you to improve the product and thus sell more (or increase the price) in the future.

A Real-World Example

The start-up that I co-founded, Binpress, is a marketplace for source-code components. One of our components, an import and export rules module for Magento, started out priced very low: $4.99 for a basic license, which is actually the minimum price that we allow.

We noticed that it was getting good traction and that people were looking for this particular functionality and that no good alternatives existed. We suggested to the developer that he raise the price. And he did, in stages:

  • At first, he raised the price to $9.99, which did not affect sales (i.e. the conversion rate stayed the same);
  • He then raised the price to $14.99 — again, the rate of sales remained the same;
  • The price is now $19.99, and sales are slowing down somewhat.

So, the optimized point lies somewhere between $14.99 and $19.99 — more than three times the original price! That is, the developer will generate over three times the revenue simply by optimizing the price and not actually changing the product. Without having tested different points, the developer would still be stuck at $4.99.


The prices should attract your customers, not drive them away. Image Source

Pricing A New Product

So far, I’ve talked about perceived and objective value and maximizing the demand curve. But what about the initial price tag?

When you go about pricing a product, run through the following exercise.

1. Determine the Product’s Objective Value

How much would people pay if they were indeed rational decision-making machines. With software, the calculation can be as simple as:

(Hourly rate × Development time in hours) − Price = Value

This simple calculation would determine the product’s value if the customer were making a completely logical decision. (Of course, this will vary depending on the hourly rate of the developer and their experience, which will affect development time. But those two numbers are usually related.)

2. Understand the Product’s Perceived Value

Who is your target audience? How will the product help them? (Will it save them time, improve their business, etc.?) Who will ultimately be making the decision to buy your product? (A developer? A project manager? The dude holding the company’s credit card?)

To answer these questions, research your market. What are the competing products? What is the demand? Who needs this solution, and how unique is it? How hard would it be to develop the product from scratch?

The Programmers section of StackExchange has a good overview of these considerations. Unless your circumstances are highly unusual, you can find answers to these questions relatively easily by using Google and by visiting relevant community-powered forums and Q&A websites such as StackExchange.

3. What Value Do I Want to Convey Though the Price?

A product priced at $1.99 sends a very different message to potential customers than one priced at $19.99 — the difference in conveyed value is by an order of magnitude. Don’t lower the price early on merely to try to generate more sales, because you would be conveying to customers that the product is worthless.

After determining the perceived value of the product and deriving a price from that, we can try to optimize the price in several ways…

1. Improve Perceived Value With Marketing

I’ve already covered several factors related to marketing, such as copy, visual design and demos, and I might expand on others in a future post. Consider these elements when trying to increase perceived value. If we find that the perceived value is below our objective value, then we can almost certainly raise it to at least the objective value. And with creative marketing, we could probably go far past that.

2. Improve Objective Value

To quote Joel Spolsky in his excellent article on Simplicity (bolding is mine):

With six years of experience running my own software company I can tell you that nothing we have ever done at Fog Creek has increased our revenue more than releasing a new version with more features. Nothing. The flow to our bottom line from new versions with new features is absolutely undeniable. It’s like gravity. When we tried Google ads, when we implemented various affiliate schemes, or when an article about FogBugz appears in the press, we could barely see the effect on the bottom line. When a new version comes out with new features, we see a sudden, undeniable, substantial, and permanent increase in revenue.

Going back to the point I made earlier, you can price higher through differentiation if you understand what people need and then exploit weaknesses in the competition. Everybody uses Magento because it delivers a lot of value, but customers keep complaining about its speed, among other things. Suppose you built a similar e-commerce platform that is blazingly fast? Bingo! You’ve targeted the biggest pain point for your competitor’s clients. Sometimes, having competition is helpful just to know what people really need.

3. Testing

When all is said and done, determining the ideal price from the get go is hard. You’ll need to test several prices and plot the demand curve of your product to find that sweet spot.

4. Tiered Pricing

This is critical from a psychological point of view. By setting just one price for your product, you don’t provide any points of reference (except those of your competition). You can increase the perceived value of your regular price by adding a premium package that is priced much higher. The point of the premium package is not to generate revenue (although it will do that — always give people the option to pay more if they want to), but rather to make the regular price seem like a better deal.

Basecamp pricing options

Start With A Good Guess And Then Optimize

By now, you should have the basic process down for how to price your product. There are no absolute truths in pricing: it’s best to start from a good guess and then test as much as possible. This article is meant to lay out the process to make that initial guess and the considerations that go into it.

There could be any number of reasons why a product is not selling as well as it should, aside from pricing. Always try to get feedback from potential customers (i.e. your website’s visitors) using tools such as KISSinsights, Total Feedback and even a simple contact form. The reasons could be a lack of information, missing features or simply a broken purchasing link.

What experience do you have in pricing software? I would love to hear about it and any questions you have in the comments!

Related Articles

You might be interested in the following related articles:

Front Cover: Image Source.

(al)


© Eran Galperin for Smashing Magazine, 2011.


Getting Started With The PayPal API


  

PayPal is the most popular platform for receiving online payments today. The ease of opening a PayPal account and receiving payments compared to opening a merchant account with a traditional payment gateway is probably the number one reason for its popularity, with a close second being the comprehensive API that PayPal provides for its payment services.

Disclaimer: PayPal’s API is among the worst I’ve ever had to deal with. Inconsistencies, sometimes poor or conflicting documentation, unpredictable failures and account changes, and major differences between the live and sandbox versions all conspire to make the PayPal API quite a pain in the arse to work with. Over the years, I’ve taken my lumps from working quite a bit with the PayPal API, and I’ve published the results of my hard-learned lessons as a commercial PHP PayPal API component on the source-code marketplace Binpress.

In this post, I will break down some of the techniques and approaches to working with the PayPal API, in order to make integration and troubleshooting simpler and easier.

PayPal at LeWeb, Copyright Jean-Christophe Capelli, Some Rights Reserved

The Different Payment Options

PayPal offers a variety of payment options, which might be confusing at first:

  • Express Checkout
    The premier PayPal service. Express Checkout allows you to receive payments without having a merchant account and without having to meet special requirements other than verifying your account (either via a bank account or a credit card). Previously, you could receive Express Checkout payments from PayPal users only, but PayPal has since added a credit-card option for non-PayPal users, making this service accessible to practically anyone with a major credit card. Note that the Express Checkout process occurs on PayPal’s platform and thus can never be fully integrated in your website’s experience.
  • Direct Payment
    The Direct Payment method allows you to receive credit-card payments directly through an API call. This enables you to host the payment process on your website in full, which might make for a more complete shopping experience for your customers. The Direct Payment method has several variations that enable you to authorize a payment and complete it at a later date: the appropriately named Authorization and Capture methods. These variations are a part of the Website Payments Pro API, which is available only to US, Canadian and UK accounts.
  • Recurring Payments
    This allows you to set up a recurring transaction (i.e. a subscription payment).
  • Mass Payments
    This allows you to transfer money to multiple accounts at once.
  • Adaptive Payments
    Here is another API for sending funds to multiple recipients, with some differences from the Mass Payments API. (Did I mention that the PayPal API is confusing and a bit redundant?)

This list is not comprehensive, but it covers the main payment options (see the API documentation for more).

Making API Requests

PayPal supports two main formats over HTTP: NVP and SOAP. NVP is short for Name-Value Pair, and SOAP stands for Simple Object Access Protocol. I will cover the NVP approach, which I prefer to SOAP’s relatively verbose and complex syntax.

Each of the API methods has different parameters, but they all share some basic parameters, which are used to identify the API account and sign the transaction. These include:

  • USER
    Your PayPal API user name.
  • PWD
    Your PayPal API password.
  • VERSION
    The version number of the NVP API service, such as 74.0 (the most recent as of this writing).
  • SIGNATURE
    Your PayPal API signature string. This parameter is optional if you use a certificate to authenticate.

The last required parameter is METHOD, which declares which API method we are calling.

Requests are made over HTTPS. We’ll use cURL to build our basic request, and then encapsulate the process in a class:

class Paypal {
   /**
    * Last error message(s)
    * @var array
    */
   protected $_errors = array();

   /**
    * API Credentials
    * Use the correct credentials for the environment in use (Live / Sandbox)
    * @var array
    */
   protected $_credentials = array(
      'USER' => 'seller_1297608781_biz_api1.lionite.com',
      'PWD' => '1297608792',
      'SIGNATURE' => 'A3g66.FS3NAf4mkHn3BDQdpo6JD.ACcPc4wMrInvUEqO3Uapovity47p',
   );

   /**
    * API endpoint
    * Live - https://api-3t.paypal.com/nvp
    * Sandbox - https://api-3t.sandbox.paypal.com/nvp
    * @var string
    */
   protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';

   /**
    * API Version
    * @var string
    */
   protected $_version = '74.0';

   /**
    * Make API request
    *
    * @param string $method string API method to request
    * @param array $params Additional request parameters
    * @return array / boolean Response array / boolean false on failure
    */
   public function request($method,$params = array()) {
      $this -> _errors = array();
      if( empty($method) ) { //Check if API method is not empty
         $this -> _errors = array('API method is missing');
         return false;
      }

      //Our request parameters
      $requestParams = array(
         'METHOD' => $method,
         'VERSION' => $this -> _version
      ) + $this -> _credentials;

      //Building our NVP string
      $request = http_build_query($requestParams + $params);

      //cURL settings
      $curlOptions = array (
         CURLOPT_URL => $this -> _endPoint,
         CURLOPT_VERBOSE => 1,
         CURLOPT_SSL_VERIFYPEER => true,
         CURLOPT_SSL_VERIFYHOST => 2,
         CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //CA cert file
         CURLOPT_RETURNTRANSFER => 1,
         CURLOPT_POST => 1,
         CURLOPT_POSTFIELDS => $request
      );

      $ch = curl_init();
      curl_setopt_array($ch,$curlOptions);

      //Sending our request - $response will hold the API response
      $response = curl_exec($ch);

      //Checking for cURL errors
      if (curl_errno($ch)) {
         $this -> _errors = curl_error($ch);
         curl_close($ch);
         return false;
         //Handle errors
      } else  {
         curl_close($ch);
         $responseArray = array();
         parse_str($response,$responseArray); // Break the NVP string to an array
         return $responseArray;
      }
   }
}

Note that I use a CA certificate file for SSL certificate validation. You can obtain the file from the cURL website or any trusted source. Update the path to the certificate file according to where you’ve placed it.

The response returned will be in NVP format as well, and I reformat it into an array before returning it. A parameter named ACK signifies the status of the request: Success or SuccessWithWarning when the request succeeds, and Error or Warning when the request fails.

A request could fail for many reasons, and there are different reasons for each API method, which are covered in detail in the manual. We’ll go over some further down in this article and look at ways to handle them. Keep in mind that the parameter values are case-sensitive, so code against them accordingly.

Express Checkout

One of the most popular APIs is the Express Checkout API, which enables you to receive payments without opening a Website Payments Pro account (which is available only to verified US accounts) or hosting the actual transaction yourself (which requires additional security).

The Express Checkout process works as follows:

  1. We request a checkout token from PayPal using the transaction details;
  2. If successful, we redirect the user to the PayPal endpoint using the received token;
  3. The user completes or cancels the payment on the PayPal platform and is redirected back to our website;
  4. We complete the payment either when the user is redirected back or via an Instant Payment Notification (IPN).

Express Checkout flow

1. Getting the Checkout Token: SetExpressCheckout

We initiate the Express Checkout process by passing the order details to the PayPal API, and we receive a token string that identifies it. This token would be used in the next step to redirect to PayPal.

Here are the required parameters:

  • METHOD
    This is the API method that we’re using (i.e. SetExpressCheckout).
  • RETURNURL
    The URL that the user will be redirected to after the payment process is completed.
  • CANCELURL
    The URL that the user will be redirected to after having cancelled the payment process.
  • PAYMENTREQUEST_0_AMT
    The transaction’s total amount. This must have two decimal places, with the decimal separator being a period (.). The optional thousands separator must be a comma (,).
  • PAYMENTREQUEST_0_ITEMAMT
    The total cost of the items in the order, excluding shipping, taxes and other costs. If there are no extra costs, then it should be the same value as PAYMENTREQUEST_0_AMT.

We can pass additional parameters to add more information about the order, some of which have default values:

  • PAYMENTREQUEST_0_CURRENCYCODE
    The payment’s currency, as a three-letter code. The default is USD.
  • PAYMENTREQUEST_0_SHIPPINGAMT
    The total shipping costs for this order.
  • PAYMENTREQUEST_0_TAXAMT
    The total tax amount for this order. This is required if per-item tax is specified (see below).
  • PAYMENTREQUEST_0_DESC
    The order’s description.

We can also add details about individual items in the order:

  • L_PAYMENTREQUEST_0_NAMEm
    The item’s name.
  • L_PAYMENTREQUEST_0_DESCm
    The item’s description.
  • L_PAYMENTREQUEST_0_AMTm
    The item’s cost.
  • L_PAYMENTREQUEST_0_QTYm
    The quantity of an item.

The variable index m identifies the item. (Use the same variable for all details of the same item.)

There are many other optional parameters, which can be found in the API documentation.

We’ll use the function that we wrote above to build the SetExpressCheckout request:

//Our request parameters
$requestParams = array(
   'RETURNURL' => 'http://www.yourdomain.com/payment/success',
   'CANCELURL' => 'http://www.yourdomain.com/payment/cancelled'
);

$orderParams = array(
   'PAYMENTREQUEST_0_AMT' => '500',
   'PAYMENTREQUEST_0_SHIPPINGAMT' => '4',
   'PAYMENTREQUEST_0_CURRENCYCODE' => 'GBP',
   'PAYMENTREQUEST_0_ITEMAMT' => '496'
);

$item = array(
   'L_PAYMENTREQUEST_0_NAME0' => 'iPhone',
   'L_PAYMENTREQUEST_0_DESC0' => 'White iPhone, 16GB',
   'L_PAYMENTREQUEST_0_AMT0' => '496',
   'L_PAYMENTREQUEST_0_QTY0' => '1'
);

$paypal = new Paypal();
$response = $paypal -> request('SetExpressCheckout',$requestParams + $orderParams + $item);

2. Redirecting to PayPal Using the Checkout Express Token

If the request is successful, we’ll receive a checkout token in the TOKEN parameter of the response.

if(is_array($response) && $response['ACK'] == 'Success') { //Request successful
      $token = $response['TOKEN'];
      header( 'Location: https://www.paypal.com/webscr?cmd=_express-checkout&token=' . urlencode($token) );
}

The user now goes through the purchase process on PayPal’s website. When they confirm or cancel it, they will return to one of the URLs that we’ve specified in the request.

3. Completing the Transaction

Assuming the user confirms the transaction, they will be redirected to our website by PayPal. At this point, we should use two relevant API methods: DoExpressCheckoutPayment will complete the transaction, but before that we might want to get additional information on the buyer using GetExpressCheckoutDetails.

PayPal will redirect the user back from the purchase with the checkout token, which we will use to call those methods. The token will be available in the URL query parameters via the token parameter. We will check for its existence in the confirmation URL and then send our API requests if we find it.

The GetExpressCheckoutDetails method requires only the checkout token. DoExpressCheckoutPayment requires a couple of additional parameters:

  • PAYMENTREQUEST_0_PAYMENTACTION
    This is the payment action. It should be set to Sale unless we’ve specified a different action in the SetExpressCheckout method (possible values include Authorization and Capture).
  • PAYERID
    This is the unique identification for the PayPal account. This, too, is returned in the URL query parameters (in the PayerID parameter) and can also be retrieved from the details returned by GetExpressCheckoutDetails.
if( isset($_GET['token']) && !empty($_GET['token']) ) { // Token parameter exists
   // Get checkout details, including buyer information.
   // We can save it for future reference or cross-check with the data we have
   $paypal = new Paypal();
   $checkoutDetails = $paypal -> request('GetExpressCheckoutDetails', array('TOKEN' => $_GET['token']));

   // Complete the checkout transaction
   $requestParams = array(
      'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
      'PAYERID' => $_GET['PayerID']
   );

   $response = $paypal -> request('DoExpressCheckoutPayment',$requestParams);
   if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
      // We'll fetch the transaction ID for internal bookkeeping
      $transactionId = $response['PAYMENTINFO_0_TRANSACTIONID'];
   }
}

Direct Payment

The Direct Payment API allows you to receive payments directly on your website or application, giving you complete control over the checkout process. PayPal tends to push users to register and use a PayPal account, which is understandable, but this conflicts somewhat with our interest to make the payment process as simple and clear as possible for our customers. For this reason, full control over the checkout process is preferred and gives us more options to optimize sales and generate more sales.

Direct Payment flow

The process is a bit simpler than that of Express Checkout, because the entire interaction occurs on our website, and we need to perform just one API call to process a normal payment: DoDirectPayment.

A couple of more API requests are required if you want to perform a transaction that is billed at a later date (for example, when you ship the product or confirm availability). These would be the Authorization & Capture API methods, which I will not cover in this post, but be aware that this option exists.

DirectPayment Parameters

DirectPayment requires different parameters than Express Checkout, as to be expected. While the transaction details parameters are similar (with different key names, to make it more interesting), the method also requires credit-card and address information.

DirectPayment’s basic parameters:

  • METHOD
    This is DoDirectPayment.
  • IPADDRESS
    This is the IP address of the payer. In PHP, we can retrieve it using the superglobal $_SERVER['REMOTE_ADDR']. You’ll have to do a bit more work to get the IP when dealing with set-ups that have a proxy between the PHP process and the outside network (such as nginx).
  • PAYMENTACTION
    This is the type of action that we want to perform. A value of Sale indicates an immediate transaction. A value of Authorization indicates that this transaction will not be performed immediately, but rather will be captured later using the Authorization & Capture API mentioned earlier.

Credit-card details:

  • CREDITCARDTYPE
    The credit-card type (Visa, MasterCard, etc.). See the API documentation for the full list.
  • ACCT
    The credit-card number. (Don’t you love these abbreviated key names?) This must conform to the particular format of the card’s type.
  • EXPDATE
    The expiration date, in MMYYYY format (i.e. a two-digit month and a four-digit year, as one string).
  • CVV2
    The “card verification value,� or security code, as it’s sometimes known.

Payer information and address parameters:

  • FIRSTNAME, LASTNAME
    The payer’s first name and last name, respectively (in separate fields). You can also provide an email address in an EMAIL parameter, but it’s not required.
  • CITY, STATE, COUNTRYCODE, ZIP
    The city, state, country code (as a two-letter code) and zip code parts of the address, all required.
  • STREET, STREET2
    Two lines for the address (only the first is required).

This address will be used in the address verification system (AVS). You’ll receive a specific error code if a transaction has failed due to an address verification failure.

The payment details parameters are the same as the ones for Express Checkout, but with slightly different names (AMT, ITEMAMT, CURRENCYCODE, SHIPPINGAMT, TAXAMT and DESC) and without the PAYMENTREQUEST_0_ prefix. Refer to the previous section or the API documentation for specific details on those.

Similarly, the item details parameters are similar to those of Express Checkout. These include L_NAMEm, L_DESCm, L_AMTm and L_QTYm, giving you granular control of item details in the order summary. The m integer variable is used to account for multiple items (replace with 0, 1 and so on for numbered items in the order). See the API documentation for a comprehensive list of item details.

Performing the Transaction

Sending the request using our function is very similar to GetExpressCheckoutToken. We pass all of the parameters into the request function as before, with the method set to DoDirectPayment.

$requestParams = array(
   'IPADDRESS' => $_SERVER['REMOTE_ADDR'],
   'PAYMENTACTION' => 'Sale'
);

$creditCardDetails = array(
   'CREDITCARDTYPE' => 'Visa',
   'ACCT' => '4929802607281663',
   'EXPDATE' => '062012',
   'CVV2' => '984'
);

$payerDetails = array(
   'FIRSTNAME' => 'John',
   'LASTNAME' => 'Doe',
   'COUNTRYCODE' => 'US',
   'STATE' => 'NY',
   'CITY' => 'New York',
   'STREET' => '14 Argyle Rd.',
   'ZIP' => '10010'
);

$orderParams = array(
   'AMT' => '500',
   'ITEMAMT' => '496',
   'SHIPPINGAMT' => '4',
   'CURRENCYCODE' => 'GBP'
);

$item = array(
   'L_NAME0' => 'iPhone',
   'L_DESC0' => 'White iPhone, 16GB',
   'L_AMT0' => '496',
   'L_QTY0' => '1'
);

$paypal = new Paypal();
$response = $paypal -> request('DoDirectPayment',
   $requestParams + $creditCardDetails + $payerDetails + $orderParams + $item
);

if( is_array($response) && $response['ACK'] == 'Success') { // Payment successful
   // We'll fetch the transaction ID for internal bookkeeping
   $transactionId = $response['TRANSACTIONID'];
}

There are plenty of parameters, but all relatively simple.

Error Handling

In a perfect world, this section would not exist. In reality, you will be referring to it quite a lot. PayPal can fail a transaction for a multitude of reasons, not all of which you can control.

The $response variable we returned from our paypalApiRequest() function could contain a different value than Success for the ACK parameter. That value could be:

  • Success
    Indicates a successful operation.
  • SuccessWithWarning
    Indicates a successful operation, and that messages were returned in the response that you should examine.
  • Failure
    Indicates a failed operation, and that the response contains one or more error messages explaining the failure.
  • FailureWithWarning
    Indicates a failed operation, and that messages were returned in the response that you should examine.

This gives us two success statuses and two failure statuses. The mock code above tests for the Success value only, but we could change it to check for SuccessWithWarning as well; and keep in mind that we need to find out what the warning is. A common scenario is that a Direct Payment charge will have been performed successfully, but the credit-card company responds that the transaction has failed, for whatever reason.

Errors from PayPal are returned in four parameters in the response:

  • L_ERRORCODE0
    A numeric error code, which can referenced against PayPal’s error code list (there are quite a few).
  • L_SHORTMESSAGE0
    A short error message describing the problem.
  • L_LONGMESSAGE0
    A longer error message describing the problem.
  • L_SEVERITYCODE0
    The severity code. (I couldn’t find any useful documentation on this, and it doesn’t really matter, so let’s put it aside.)

The 0 part of these parameters is an incrementing integer for multiple error message (1, 2, etc.).

Here are some common errors you’ll run into:

  • 10002
    Authentication or authorization failed. This usually indicates invalid API credentials, or credentials that do not match the type of environment you are working in (such as a live or sandbox environment).
  • 81***
    Missing parameter. There are quite a few of these, all starting with 81. Each refers to a specific required parameter that is missing from the request.
  • 104**
    Invalid argument. This indicates that one of the supplied parameters has an invalid value. Each argument has specific errors, all starting with 104. A common one is 10413, which means that the total cost of the cart items does not match the order’s amount (i.e. the total amount parameter, AMT, does not equal the items’ total plus shipping, handling, taxes and other charges).

How Do We Handle These Errors in Practice?

PayPal error messages vary and could contain private information that you do not want your users to see (such as an invalid merchant configuration). That being the case, showing PayPal error messages directly to users is not advisable, even though some of them might be useful.

In most cases, I would do the following:

  1. Set up a white-list array of errors that can be shown safely (such as a missing credit-card number and expiration date);
  2. Check the response code against that array;
  3. If the error message is not white-listed, then display a generic message, such as “An error has occurred while processing your payment. Please try again in a few minutes, or contact us if this is a recurring issue.�

If an error falls outside of the white-listed array, I will also log it to a file on the server and send an email to the administrator, with the full details so that someone is up to speed on payment failures. In fact, logging PayPal requests and responses is good practice regardless of errors, so that you can monitor and troubleshoot payment failures (I provide this option in the commercial component that I mentioned at the beginning of this article).

Ready To Get Started With The PayPal API?

In this post, I’ve covered two of the most widely used API methods, as well as error handling with the PayPal API. This should be enough for you to get started using the most popular payment platform online.

The PayPal API has many more methods and processes, more than can be covered in any one post. Once you get up to speed on the basic methods, learning the others should be relatively straightforward (even if somewhat exhausting). I hope this guide has given you a good head start on using the API. If you have questions or comments, I would love to hear from you in the comments!

Front cover: Image source

(al)


© Eran Galperin for Smashing Magazine, 2011.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress