Direct Receipts & IPNs

A Direct Receipt allows the DigiResults servers to communicate with your webserver with details about a purchase as and when it happens, independent of any hits by your customers.

Please Note: Most of the time using one of the methods described on “How do I protect my download” is sufficient, but if you want more control, and have the required programming skill, Direct Receipts is one way to go.

These operate by sending an HTTP POST request with parameters (detailed below) to the URL you specify in your product’s advanced settings.

There are two types of Direct Receipts that DigiResults can send to your servers matching the functionality of ClickBank’s receipts or PayPal’s “Instant Payment Notifications”.

ClickBank style Direct Receipts

The first thing your page should do is check that the Direct Receipt is valid—the following PHP snippet will do that. You will need to set $secretKey to the value found on your ‘Manage > Account’ page.

<?php
function direct_receipt_is_valid() {
  $secretKey = "<REPLACE ME REPLACE ME>"; // Replace with the actual value
  $pop = "";
  $keys = array( 'ccustname', 'ccustemail', 'ccustcc', 'ccuststate',
    'ctransreceipt', 'cproditem', 'ctransaction', 'ctransaffiliate',
    'ctranspublisher', 'cprodtype', 'cprodtitle', 'ctranspaymentmethod',
    'ctransamount', 'caffitid', 'cvendthru'
  );

 foreach ($keys as $field) {
    // if Magic Quotes are enabled $_POST[$field] will need to be
    // un-escaped before being appended to $pop
    $pop = $pop . $_POST[$field] . "|";
  }
  $pop = $pop . $secretKey;

  $calcedVerify = strtoupper( substr( sha1( $pop ), 0, 8 ) );
  return $calcedVerify == $_POST["cverify"];
}

if ( !direct_receipt_is_valid() ) {
  exit;
}
// The receipt is valid, so register the sale in your system
// or add the user to your membership site here
?>

This works by comparing the parameters in a fixed order and using a cryptographic hash function with data that is only known to you and DigiResults (and not present in the POST params).

ccustname
Customer’s Name (‘First Last’)
ccustemail
Customer’s Email address
ccustcc
Customer’s Country Code (‘US’, ‘CA’, etc.)
ccuststate
Customer’s State (if available)
ctransreceipt
Receipt ID. For recurring payments this will be same across all transactions for this profile
cproditem
The DigiResults Product ID
ctransaction
Transaction type. One of:
SALE
Normal sale or first sale of a subscription
RFND
Refund of a normal purchase.
BILL
A rebill for a recurring product.
CANCEL-REBILL
Termination of a recurring billing profile. This is sent when the paid period has expired, not when the cancellation happens.
ctransaffiliate
The ID of the affiliate on this sale (if there was one)
ctranspublisher
Your DigiResults user ID
cprodtype
Product type. STANDARD for normal payments and RECURRING for subscription payments
cprodtitle
Product Name. If a variant was purchased then it will be ‘Product – Variant’.
ctranspaymentmethod
Payment method. Currently always PYPL (PayPal)
ctransamount
The amount paid in cents. i.e. $27.00 would have a value of 2700 in this field
caffitid
Empty string
cvendthru
Custom parameters from buy link. More about custom parameters
ctranstime
Time of the original sale as seconds since the Epoch.
dplankey
Tracking key to tie together payments on a payment plan
dvariant
If a variant is sold then the id will appear here

Paypal style Instant Payment Notifications

We need simpler processing for the PayPal IPNs – we just need to read in the parameters.

NOTE: You will be unable to verify these IPNs with PayPal. This means that scripts that expect PayPal’s IPNs will need modifying before use.

The following fields are used:

mc_gross
The total paid in the currency shown
tax
The amount of tax paid by the customer
payment_date
The timestamp of the sale
payment_status
The status of this payment
charset
The encoding of the text fields
first_name
The customer’s first name
last_name
The customer’s last name
payer_status
The status of the customer’s PayPal account
business
Your PayPal account email address
payer_email
The customer’s PayPal email address
txn_id
The transaction id for this payment
address_country_code
Customer’s country code
receiver_email
Your email address
payment_fee
Total PayPal fees paid by you on the transaction
item_name
The name of the item purchased
residence_country
The customer’s country of residence
payment_gross
The gross amount paid
mc_currency
The shown currency of the transaction (this will always be USD)
custom
Custom parameters. More about custom parameters.

These fields will be sent as empty strings for all DigiResults transactions and should be ignored in your processing

  • address_name
  • address_street
  • address_city
  • address_zip
  • address_state
  • address_country
  • mc_fee
  • quantity
  • shipping_discount
  • insurance_amount
  • discount
  • item_number
  • shipping_method
  • handling_amount
  • shipping
  • verify_sign
  • ipn_track_id
  • btn_id

Please referrer to PayPal’s IPN documentation for the meaning of following fields:

  • protection_eligibility
  • payer_id
  • notify_version
  • payment_type
  • receiver_id
  • txn_type
  • transaction_subject

Passing custom fields to your Direct Receipt scripts

If you need to associate a payment with an existing user on your system or you just need to track some other bit of state with to process the DirectReceipt you can do this by passing query string parameters to the buy url.

For example http://www.digiresults.com/buy/2?custid=23&level=1 would send custid=23&level=1 to the Direct Receipt script (either in the cvendthru or custom fields depending on the format of the Direct Receipt you are using.

To easier support existing PayPal IPN scripts if you send a custom query parameter then the value of this parameter will be the sole value of the custom field in the PayPal-format DirectReceipt. For example /buy/2?custom=23 would give custom of “23″, where as /buy/2?custid=23&level=1 would give a custom field of “custid=23&level=1″

Passing multiple values

You can happily use multiple custom values and they will be sent back to you URL-escaped as a single parameter. To split them out again you will need to parse the string. For example in PHP:

parse_str( $_POST[ 'cvendthru' ], $custom_fields ); // or $_POST[ 'custom' ]
// $custom_fields[ 'custid' ] now set.