Selling Digital Products with StayPal

Illustration of myriad international currencies falling from the sky, with the text "StayPal" overlayed

While we anxiously await the Trading Post, we lack quick and easy ways to integrate add-on sales with a Statamic-powered site. However, I wrote a plugin called StayPal that makes it simple.

This concept works for any digital products you might want to sell. Add-ons are used only as an example.

To make this work, you need to create/edit:

  1. an add-on fieldset,
  2. a StayPal settings file,
  3. an add-on template,
  4. a template for the page your customers return to after a purchase, and
  5. a page
    • whose URL is designated in the return parameter of the StayPal tag and
    • uses the template from #4.

Add-on Fieldset

A super-simplified version of my add-on fieldset looks like this:

    display: Price
    type: text

    display: Download Directory
    type: text

I generate a random string using 1Password to name a download directory and drop the add-on .zip in there. So… yes, anyone could potentially figure out a way to download my publicly-accessible add-ons for free, but I plan to take this temporary solution down once the Trading Post launches. Also, I doubt anyone would waste their time trying to figure out the random strings.

Temporary + Security Through Random String = Works For Me. Do what works for you.

Make sure you input only price-formatted numbers in the price field. It gets sent to PayPal and can’t contain things like currency symbols.

StayPal Settings File Excerpt

This belongs in _config/add-ons/staypal/staypal.yaml.

Don’t forget to update:

  1. business,
  2. cert_id, and perhaps
  3. currency_code.

cmd: _xclick

# Assuming you work with US dollars. If not, update to the appropriate 
# three-letter currency code.
currency_code: USD

# Don't prompt for an address.
no_shipping: 1

# Use POST. This allows you to give your customers purchase info and
# a download link w/o showing that info in the URL.
rm: 2

Add-on Template

Inside your add-on template, you need to use a StayPal tag:

{{ staypal:encrypt
    item_name    = '{ title }'
    amount       = '{ price }'
    cancel_url   = '{ _site_url }{ url }'
    return       = '{ _site_url }{ path src="thanks" }'
    custom       = '{ _site_url }/{ download_dir }/{ title|lower|slugify }.zip'
    button_text  = 'Buy <strong>{ title }</strong> for ${ price }'

You can change things up a bit, but currently this requires you to:

  1. have your download directories at root,
  2. zip the download files and name the .zip a lowercase slugified version of your add-on’s name, and
  3. have an entry at

Whatever you pass to custom can be grabbed as a POST variable later. This code uses it to make sure customers get the right download link.

Return Template aka The Wizardry

Now that we have everything else set up, we can use {{ get_post }} to retrieve information about the purchase.

See IPN and PDT Variables for a full list of returned POST variables you can use.

{{ if {get_post:payment_status} == "Completed" OR
      {get_post:payment_status} == "Processed"

  <h1>You purchased {{ get_post:item_name }}.</h1>
  <p><a href="{{ get_post:custom }}">Download {{ get_post:item_name }}</a></p>

{{ else }}

  <p>There was an error.</p>

{{ endif }}

<p>Total: ${{ get_post:mc_gross }}</p>
<p>ID: {{ get_post:txn_id }}</p>
<p>Payment Status: {{ get_post:payment_status }}</p>

  If you have any problems,
  <a href="{{ obfuscate }}{{ /obfuscate }}">send me an email</a>.

Return Page

On my site, I left everything blank and set the template to the one discussed in the previous section.

comments powered by Disqus