ClickBank Knowledge Base /General Account Help/Tools & Features

Instant Notification Service

Melissa
posted this on December 26, 2012, 13:14

ClickBank offers an Instant Notification service that notifies you of transactions within the ClickBank system for your account. It sends data to you in a near real-time fashion for the following events:

  • Sale – The sale of a standard product or initial sale of a recurring product.
  • Rebill – A rebill for a recurring product.
  • Refund – A refund for a standard or recurring product.
  • Chargeback – A chargeback for a standard or recurring product.
  • Cancel Rebill – The canceling of a recurring product.
  • Un-cancel Rebill – The reversal of a cancelation for a recurring product.
  • Test Transactions – Test transactions for the types listed above, or a test of the instant notification feature that you initiate.

The service attempts to post information via HTML FORM POST to a URL specified by you. Each post contains a group of URL Parameters relevant to the transaction. The notification is encrypted, and must be decrypted using your secret key and the initialization vector before it can be processed.

NOTE  This service is intended for use by experienced programmers. If you don't have programming experience, you should find a developer who can help you before enabling instant notifications.

The following subjects are covered in this article:

Overview

Once enabled, the Instant Notification service is triggered every time a transaction is created or an action is taken upon a transaction in your ClickBank account. The primary flow involves the following steps:

  1. An action occurs in the ClickBank system (such as a sale or rebill).
  2. Clickbank encrypts a notification using your secret key and an initialization vector.
  3. ClickBank posts HTML FORM parameters to a URL you specify.
    Your URL should use Transport Layer Security (TLS) or Secure Socket Layer (SSL).
  4. ClickBank uses Response Code Monitoring to verify that the notification was received.
  5. An application you build decrypts the message (using your secret key and the initialization vector) and processes the post parameters.

Setting up the service on your ClickBank account is straightforward. However, you must also build an application that processes the instant notification URL parameters, which is a more technical task. In order to make good use of this service, your application must, at a minimum, process the parameters outlined in the Parameters section of this document.

If you don't understand all of these steps, we recommend that you enlist the services of a developer who can help you. If you implement Instant Notifications incorrectly, we may disable or remove the feature from your account.

Current Version

The current version of the Instant Notification feature is 6.0.

New features in version 6.0 include:

  • Encrypted notifications
  • Parameters indicating the type of order that included the purchase (such as an upsell or order bump)
  • Quantity parameter
  • Vendor-specific variable parameters

See the Legacy Versions section for information about the parameters used by older versions. Older versions of Instant Notification do not encrypt the notification, so we do not recommend their use.

Notification Format

This section describes the format of the instant notification sent to you.

Base Structure

Instant Notifications are created in the JSON format. They are encrypted prior to sending.

The base structure of an instant notification is:

{"notification": "<ENCRYPTED_NOTIFICATION>", "iv": "<INITIALIZATION_VECTOR>"}

Encryption

ClickBank uses the CBC-AES-256 encryption algorithm to secure the payload of the notification.  This helps prevent customer information from being passed in clear text, and allows the receiver of the notification to know that the message originated from ClickBank and was not altered during delivery.  Several examples of how to decrypt the notification are listed in the Code Samples section, but you should familiarize yourself with the AES-256 encryption algorithm to have a better understanding of how it works.

The initial JSON message contains a string representation of the encrypted notification, and the initialization vector which you can use in parallel with your ClickBank secret key to decrypt the notification.

Parameters

This section describes all of the parameters used in a notification.

When a notification is sent, it includes all parameters. If a parameter contains no value, the instant notification string contains the parameter tag without a value. This is why the number of characters for some parameters includes zero, as these parameters may not contain a value.

Header Parameters

Parameter Description Characters / Format Recipient
transactionTime Time of transaction in RFC-3339 format 25 All
receipt ClickBank receipt ID 8-21 All
transactionType The type of transaction. 4-15 – See Transaction Types All
vendor The vendor nickname 5-10 All
affiliate The affiliate nickname 5-10 All
role Your role in the transaction 6-9 – VENDOR, AFFILIATE, or JV_VENDOR All
totalAccountAmount Total you received for the transaction in USD Numeric with 2 decimal precision All
paymentMethod Payment method used by the customer. 3-4 – See Payment Methods All
totalOrderAmount Total the customer was charged Numeric with 2 decimal precision All
totalTaxAmount Total the customer paid in taxes Numeric with 2 decimal precision Vendor
totalShippingAmount  Total the customer paid in shipping Numeric with 2 decimal precision Vendor
currency Currency the user paid in 3 Vendor
orderLanguage Language used on the order form 2 – DE, EN, ES, FR, IT, or PT Vendor
trackingCodes Any tracking codes passed into the order form. 0-24 each Vendor, Affiliate

Product Parameters

Parameter Description Characters / Format Recipient
itemNo SKU of the product ordered 1-10 All
productTitle Product title 0-255 All
shippable Whether the product was a physical good 4-5 – true or false All
recurring Whether the product was subscription-based 4-5 – true or false All
accountAmount Amount you received on this line item Numeric with 2 decimal precision  All
quantity Quantity of item purchased Numeric All
downloadUrl Product download URL for the customer 0-255 Vendor
lineItemType Type of order the line item was part of 4-8 – ORIGINAL, CART, BUMP, TOKEN, or UPSELL All

Customer Shipping Parameters

Parameter Description Characters Recipient
firstName Customer's first name 0-255 Vendor
lastName Customer's last name 0-255 Vendor
fullName Customer's first and last name 0-255 Vendor
phoneNumber Customer's phone number 0-255 Vendor
email Customer's email address 0-255 Vendor
address1 Customer's physical address, line 1 0-255 Vendor
address2 Customer's physical address, line 2 0-255 Vendor
city Customer's city 0-255 Vendor
county Customer's county 0-255 Vendor
state Customer's state 0-255 Vendor
postalCode Customer's postal code or zip code 0-255 Vendor
country Customer's country 0-255 Vendor

Customer Billing Parameters

Parameter Description Characters Recipient
firstName Customer's first name 0-255 Vendor
lastName Customer's last name 0-255 Vendor
fullName Customer's first and last name 0-255 Vendor
phoneNumber Customer's phone number 0-255 Vendor
email Customer's email address 0-255 Vendor
state Customer's state 0-255 All
postalCode Customer's postal code or zip code 0-255 All
country Customer's country 0-255 All

Upsell Parameters

Parameter Description Characters Recipient
upsellOriginalReceipt Receipt number that started the upsell flow 8-21 All
upsellFlowId ID of the upsell flow Integer Vendor
upsellSession Session ID for the upsell 0-16 Vendor
upsellPath Upsell path 0-12 Vendor

Pytch Parameters

NOTE – The Pytch feature has been deprecated, but the parameters are retained for backwards compatibility purposes.

Parameter Description Characters / Format Recipient
hopfeedClickId Hopfeed click ID name  String  All
hopfeedApplicationId Application ID Numeric  All
hopfeedCreativeId Creative ID  Numeric  All
hopfeedApplicationPayout Application Payout  Numeric with 2 decimal precision  All
hopfeedVendorPayout Vendor Payout  Numeric with 2 decimal precision  All

Technical Parameters

Parameter Description Format Recipient
version The version of the instant notification. Double Numeric All
attemptCount The number of times ClickBank tried to send this notification before receiving a success or failing with too many attempts Integer All

Vendor Parameters

If the vendor has provided any additional variables to the paylink, they are also provided in the notification as parameters called v1, v2, and so on.

Transaction Types

There are a number of values you can receive in the transactionType parameter. These values are listed below with a brief description of their purpose.

NOTE – Notifications for test transactions are only sent to the vendor.

Type Description
SALE The purchase of a standard product or the initial purchase of recurring billing product.
BILL A rebill for a recurring billing product.
RFND The refunding of a standard or recurring billing product. Recurring billing products that are refunded also result in a "CANCEL-REBILL" transaction.
CGBK A chargeback for a standard or recurring product.
INSF An eCheck chargeback for a standard or recurring product.
CANCEL-REBILL The cancellation of a recurring billing product. Recurring billing products that are canceled do not result in any other action.
UNCANCEL-REBILL Reversing the cancellation of a recurring billing product.
TEST A test transaction triggered during configuration.
TEST_BILL A test rebill for a recurring billing product.
TEST_RFND A test refund of a standard or recurring billing product.
TEST_SALE A test purchase of a standard or recurring billing product.
CANCEL-TEST-REBILL A test recurring product cancelation.
UNCANCEL-TEST-REBILL A test cancelation reversal for a recurring product.

Payment Methods

There are a number of values you can receive in the paymentMethod parameter. These values are listed below.

Payment Method Parameter Payment Method
PYPL Paypal
VISA Visa
MSTR Mastercard
DISC Discover
AMEX American Express
SOLO Solo
JCBC JCB
DNRS Diners Club
MAES Maestro
ELV European Direct Debit
TEST Test Payment

Notification Example

This is a sample of the unencrypted JSON notification showing the structure of the key-value pairs for Version 6.0 of Instant Notification. 

NOTE – The JSON format does not actually support inline comments as shown below.  They are only inlined to help you understand the data. The actual notification will be sent without the comments.

 {
    // Time of the transaction in RFC-3339 format [25 characters]
    "transactionTime": "2014-09-05T13:47:51-06:00",
    // ClickBank receipt [8 - 21 characters]
    "receipt": "CWOGBZLN",
    // Type of Transaction (SALE, BILL, RFND, CGBK, INSF, CANCEL-REBILL,
    // UNCANCEL-REBILL, TEST, TEST_BILL, TEST_RFND, TEST_SALE,
    // CANCEL-TEST-REBILL, UNCANCEL-TEST-REBILL)
    "transactionType": "SALE",
    // Vendor nickname [5 - 10 characters]
    "vendor": "testacct",
    // Affiliate nickname [5 - 10 characters]
    "affiliate": "affiliate1",
    // Your role in the transaction (e.g., VENDOR, AFFILIATE, JV_VENDOR) [6 - 9 characters]
    "role": "VENDOR",
    // Total you received for this transaction in USD [numeric value with 2 decimal precision]
    "totalAccountAmount": 0.00,
    // Payment method used by the customer. [AMEX, AUST, BLME, DISC, DNRS, ELV, ENRT, IMAS,
    // JCBC, MAES, MSTR, PYPL, STVA, SWIT, TEST, VISA]
    "paymentMethod": "VISA",
    // Total the customer was charged [numeric value with 2 decimal precision]
    "totalOrderAmount": 0.00,
    // Total the customer paid in taxes. ONLY AVAILABLE TO THE VENDOR [numeric value with 2
    // decimal precision]
    "totalTaxAmount": 0.00,
    // Total the customer paid in shipping. ONLY AVAILABLE TO THE VENDOR [numeric value with
    // 2 decimal precision]
    "totalShippingAmount": 0.00,
    // The currency the customer paid in. ONLY AVAILABLE TO THE VENDOR [3 characters]
    "currency": "USD",
    // The language displayed on the order form. ONLY AVAILABLE TO THE VENDOR
    // [DE, EN, ES, FR, IT, PT]
    "orderLanguage": "EN",
    // Any tracking codes passed into the order form. ONLY AVAILABLE TO THE VENDOR AND
    // THE AFFILIATE [0 - 24 characters each]
    "trackingCodes": [
        "tracking_code"
    ],
    // A list of products purchased on this order
    "lineItems": [
        {
            // Product SKU. [1 - 10 characters]
            "itemNo": "1",
            // Product title. [0 - 255 characters]
           "productTitle": "Product Title",
            // Was the product shippable? [true, false]
            "shippable": true,
           // Was the product subscription based? [true, false]
            "recurring": true,
            // Amount you received on this given line item. [numeric value with 2
            // decimal precision]
            "accountAmount": 0.00,
           // quantity of item purchased [numeric value]
            "quantity": 0,
           // Product download URL for the customer. ONLY AVAILABLE TO THE VENDOR
            "downloadUrl": "<download_url>"
           // What type of order was this line item? [Original, Cart, Bump, Token, Upsell]
            "lineItemType": "CART"

        }

    ],
    "customer": {
        // Shipping customer information. ALL FIELDS ARE ONLY AVAILABLE TO THE VENDOR
        // [each field is 0 - 255 characters]
        "shipping": {
            "firstName": "TEST",
            "lastName": "GUY",
            "fullName": "Test Guy",
           "phoneNumber": "",
            "email": "test@example.net",
            "address": {
                "address1": "12 Test Lane",
                "address2": "Suite 100",
                "city": "LAS VEGAS",
                "county": "LAS VEGAS",
                "state": "NV",
                "postalCode": "89101",
                "country": "US"
            }
        },
        // Billing customer information. FIELDS ARE ONLY AVAILABLE TO THE VENDOR UNLESS
        // OTHERWISE STATED [all fields are 0 - 255 characters]
        "billing": {
            "firstName": "TEST",
            "lastName": "GUY",
            "fullName": "Test Guy",
            "phoneNumber": "",
            "email": "test@example.net",
            "address": {
                // AVAILABLE TO ALL RECIPIENTS
                "state": "NV",
                // AVAILABLE TO ALL RECIPIENTS
                "postalCode": "89101",
                // AVAILABLE TO ALL RECIPIENTS
                "country": "US"
            }
        }
    },
    // If the order is part of an upsell, that information will be found here
    "upsell": {
        // ClickBank receipt number that started the upsell flow
        "upsellOriginalReceipt": "XXXXXXXX",
        // ID of the upsell flow. ONLY AVAILABLE TO THE VENDOR [integer value]
        "upsellFlowId": 55,
        // Session ID for the upsell. ONLY AVAILABLE TO THE VENDOR [0 - 16 characters]
        "upsellSession": "VVVVVVVVVV",
        // Upsell path. ONLY AVAILABLE TO THE VENDOR [0 - 12 characters]
        "upsellPath": "upsell_path"
    },
    // If there is Pytch information associated with this order, the information will be
    // found here and is available to all recipients.
    "hopfeed": {
        "hopfeedClickId": "hopfeed_click",
        "hopfeedApplicationId": 0000,
        "hopfeedCreativeId": 0000,
        "hopfeedApplicationPayout": 0.00,
        "hopfeedVendorPayout": 0.00
    },
    // Version of the instant notification. [double numeric value]
    "version": 6.0,
    // The number of attempts ClickBank has tried to send this instant notification
    // before receiving a success, or failing with too many attempts. [integer value]
    "attemptCount": 1,

   // Any vendor provided variables to the paylink will be provided here.   
    "vendorVariables": {
       "v1": "variable1", 
       "v2": "variable2" 
    }

}

Implementation

After gaining a sound understanding of the previous section of this document, you can request access to the Instant Notification feature, test your URL, and enable Instant Notifications.

Once you have configured one URL for Instant Notifications, you can add another by using these procedures with the Instant Notification 2 field.

Requesting Access to Instant Notifications

The Instant Notification feature is not automatically enabled. To request access:

  1. Log in to your account.
  2. Click the Settings tab.
  3. Click My Site.
  4. Find the Advanced Tools section and click Edit.
  5. Click the Request Access link next to the Instant Notification URL field.
  6. Fill out the form, thoroughly review the terms of use, and acknowledge that you have read and agree to the terms of use.
  7. Click the Save Changes & Request API Access button at the bottom of the form.
  8. Click the Save Changes button.

Configuring Your URL

Once you have received access to the Instant Notification feature, you must create a target URL and a program to process the Notifications that will be sent to your URL. You can use ports 80 or 443.

Transport Layer Security (TLS) and Secure Socket Layer (SSL)

It is strongly recommended that you utilize this feature with Transport Layer Security (TLS) or Secure Socket Layer (SSL) enabled. Using this feature without TLS or SSL enabled can expose your sales data to thieves. However, because credit card and bank information is not transmitted via the Instant Notification service, we do not require you to use TLS or SSL to encrypt Instant Notification transmissions.

NOTE – You cannot use a self-signed SSL certificate. You must use a valid certificate.

Testing Connectivity and Processing

Before you can enable Instant Notifications, you must test the connectivity and successful processing of the URL parameters between ClickBank and your server. To perform this test:

  1. Log in to your account.
  2. Click the Settings tab.
  3. Click My Site.
  4. Enter your URL in the Instant Notification 1 field.
    NOTE – Do not click Save Changes.
  5. Click Test to the right of the URL.
    A test notification is sent with a receipt of ******** and a transaction type of TEST.
  6. Review the response in the popup window to verify that the test was successful.

If the test was not successful, remove the URL from the Instant Notification field and troubleshoot possible problems with connectivity or your application.

NOTE – You should not populate the Instant Notification field unless you can conduct a successful test. Doing so may result in your access to the feature being disabled.

Enabling Instant Notifications

Once you have been granted access to the feature and conducted a successful test, you can enable Instant Notifications to begin receiving them. To enable Instant Notifications:

  1. Log in to your account.
  2. Click the Settings tab.
  3. Click My Site.
  4. Enter a Secret Key on your My Site page.
  5. Enter your URL in the Instant Notification 1 field.
  6. Click Test to the right of the URL.
    A test notification is sent with a receipt of ******** and a transaction type of TEST.
  7. Review the response in the popup window to verify that the test was successful.
  8. Click Save Changes.

Once the setup is complete, the Instant Notification transmissions will begin immediately.

Disabling Instant Notifications

You can disable the feature to prevent notifications from being sent by removing your URL. You can re-enable the feature later.

  1. Log in to your account.
  2. Click the Settings tab.
  3. Click My Site.
  4. Remove the URL from the Instant Notification 1 field.
  5. Click Save Changes.

Response Code Monitoring

When we send an instant notification, we monitor the response code from your URL. If the response code is in the 200 range, the notification delivery is considered successful.

If the response code is not in the 200 range, we attempt to resend the notification once per hour for 72 hours. After 72 failed attempts, we disable your URL. Once you diagnose the cause of the failures, you can re-enable your URL and resume receiving instant notifications.

Code Samples

The data sent to you by the Instant Notification service is in the form of HTML FORM POST URL Parameters. Programs written within your application architecture must process these pairs. Programs for order management, database activity, and other services may be written but are outside the scope of this guide.

The following code samples cover decrypting the notification.

NOTE – The following code samples must be nested in a program. If you do not understand, you should find a programmer who can help you.

Java

The following code sample uses Java to decrypt the notification.

 public void processNotification(final HttpServletRequest theRequest,
                              final HttpServletResponse theResponse)
   throws IOException {
  try {
     final StringBuilder buffer = new StringBuilder();
    final String secretKey = "YOUR SECRET KEY";

     try {
       String line;
        final BufferedReader reader = theRequest.getReader();
         while(null != (line = reader.readLine())) {
          buffer.append(line);
         }
      } catch(final Exception ex) {
          ex.printStackTrace();
       }

       final JSONParser parser = new JSONParser();
       final JSONObject obj = (JSONObject) parser.parse(buffer.toString()); 

      final String initializationVector = (String) obj.get("iv");
       final String encryptedNotification = (String) obj.get("notification"); 
      final MessageDigest digest = MessageDigest.getInstance("SHA-1");
      digest.reset();
       digest.update(secretKey.getBytes("UTF-8"));
      final String key = new String(Hex.encodeHex(digest.digest())).substring(0, 32);

final IvParameterSpec iv =
          new IvParameterSpec(DatatypeConverter.parseBase64Binary(initializationVector));
       final SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
      final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
       cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

      final JSONObject notification = (JSONObject) parser.parse(
      new String(cipher.doFinal(DatatypeConverter.parseBase64Binary(encryptedNotification)),
                     "ISO-8859-1"));

       //
       // Make use of the notification here...
      // 

   } catch(final NoSuchPaddingException
      | ParseException
       | NoSuchAlgorithmException
      | InvalidAlgorithmParameterException
       | BadPaddingException
      | IllegalBlockSizeException
       | UnsupportedEncodingException
      | InvalidKeyException ex) {
       ex.printStackTrace();
      theResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                             "Could not decrypt instant notification");
  }
    theResponse.setStatus(HttpServletResponse.SC_NO_CONTENT);
}

PHP

The following code sample uses PHP to decrypt the notification.

 <?php
// NOTE: the mcrypt libraries need to be installed and listed as an
// available extension in your phpinfo() to be able to use this
// method of decryption.
$secretKey = "YOUR SECRET KEY"; // secret key from your ClickBank account
 // get JSON from raw body...
$message = json_decode(file_get_contents('php://input'));
// Pull out the encrypted notification and the initialization vector for
// AES/CBC/PKCS5Padding decryption
$encrypted = $message->{'notification'};
$iv = $message->{'iv'}; error_log("IV: $iv");
// decrypt the body... $decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,                                  substr(sha1($secretKey), 0, 32),                                  base64_decode($encrypted),                                  MCRYPT_MODE_CBC,                                  base64_decode($iv)), "\0..\32"); error_log("Decrypted: $decrypted");

// convert the decrypted string to a JSON object...
$order = json_decode($decrypted);

// Ready to rock and roll - If the decoding of the JSON string wasn't
// successful, then you can assume the notification wasn't encrypted
// with your secret key.

?>

Python

The following code sample uses Python to decrypt the notification.

import hashlib
import json
from Crypto.Cipher import AES
##
# Parse ClickBank Notification
# @param message: A string representing the raw HTTP POST body
# @return: A JSON object representing the decrypted notification
def process_clickbank_notification(message):
    j = json.loads(message)
    iv = j['iv']
    encrypted_str = j['notification']
    sha1 = hashlib.sha1()
    sha1.update("YOUR SECRET KEY")
    cipher = AES.new(sha1.hexdigest()[:32], AES.MODE_CBC, iv.decode('base64'))
    return cipher.decrypt(encrypted_str.decode('base64')).strip()

Ruby

The following code sample uses Ruby to decrypt the notification.

require "base64"
require "digest/sha1"
require "json"
require "openssl"
 # Decode the IPN post into a JSON object.
# The message param is the raw HTTP POST
 # body of the notification
def decrypt_clickbank_notification(message)
  parsed = JSON.parse(message);
  aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
  aes.iv = Base64.decode64(parsed["iv"])
  aes.decrypt
  aes.key = Digest::SHA1.hexdigest("YOUR SECRET KEY").slice(0, 32)
  aes.update(Base64.decode64(parsed["notification"])) + aes.final
end

Legacy Versions

This section describes the legacy versions of the instant notification service. If you are using one of these versions, we recommend switching to version 6.0 as soon as possible.

The versions described here do not encrypt the notification, and do not contain some of the parameters included in the latest version.

Cipher

Cipher is a method of performing encryption and decryption. It ensures there has been no URL tampering of the query string parameters.

When an action occurs within your ClickBank account, several values are passed along in the Instant Notification query string. While building the string we create a sha1, or a hash of the values passed, and your Secret Key. The result is the cverify parameter. Upon receipt of the query string parameters, your system must also create a sha1, or a hash of the values passed, and your Secret Key.

The validity of the data received is evaluated by using the cverify parameter we send and the value produced in your system. Only if there is an exact match between the two values can you be certain the information received has not been tampered with.

Please see Legacy Code Samples for examples.

Version 1

The following post parameters are used in Instant Notification Version 1.

Parameter

Description

Details

caffitid

affiliate TID [only populated for affiliate]

0 – 24 characters

ccustcc

customer country code (2-characters) [only populated for vendor]

0 – 2 characters

ccustemail

customer email [only populated for vendor]

1 – 255 characters

ccustname

customer name as typed in on the order form [only populated for vendor]

1 – 510 characters

ccuststate

customer state/province [only populated for vendor]

0 – 2 characters

cproditem

product item sku

1 – 10 characters

cprodtitle

product title

0 – 255 characters

cprodtype

product type (STANDARD, RECURRING) [will also have 'Physical' if the product was a physical good]

8 – 11 characters

ctransaction*

transaction type (SALE, JV_SALE, INSF, RFND, CGBK, BILL, JV_BILL, TEST_SALE, TEST_JV_SALE, TEST_BILL,                                         TEST_JV_BILL, TEST_RFND)

4 – 15 characters

ctransaffiliate

affiliate nickname

0 – 10 characters

ctransamount

amount paid out to the recipient of the notification (in pennies (1000 = $10.00))

3 – 10 characters

ctranspaymentmethod

payment method (AMEX, AUST, BLME, DISC, DNRS, ELV, ENRT, IMAS, JCBC, MAES, MSTR, PYPL, STVA, SWIT, TEST, VISA)

0 – 4 characters

ctranspublisher

vendor nickname

5 – 10 characters

ctransreceipt

receipt number

8 – 13 characters

ctranstime**

the Epoch time the transaction occurred (not included in cverify)

10 characters

cupsellreceipt**§

 

if this transaction is part of an upsell, this is the originating receipt number.

8 – 13 characters

cvendthru

download URL [only populated for vendor]

0 – 1024 characters

cverify**

the "cverify" parameter is used to verify the validity of the previous fields

8 characters

If product is shippable and recipient is the vendor we will pass the following additional fields:

Parameter

Description

Details

ccustaddr1**

ship-to address line 1

0 – 255 characters

ccustaddr2**

ship-to address line 2

0 – 255 characters

ccustcity**

ship-to city

0 – 255 characters

ccustcounty**

ship-to county

0 – 255 characters

ccustshippingcountry**

ship-to country

0 – 255 characters

ccustshippingzip**

ship-to zip code

0 – 255 characters

ccustzip

customer zip code

0 – 16 characters

Version 2

Parameter

Description

Details

caccountamount

Amount paid to party receiving notification (in pennies (1000 = $10.00))

3 – 10 characters

ccurrency

currency the customer paid in [only populated for vendor]

2 characters

ccustaddr1

ship-to address line 1 [only populated for vendor]

0 – 255 characters

ccustaddr2

ship-to address line 2 [only populated for vendor]

0 – 255 characters

ccustcc

customer country code (2-characters) [only populated for vendor]

0 – 255 characters

ccustcity

ship-to city [only populated for vendor]

0 – 255 characters

ccustcounty

ship-to county [only populated for vendor]

0 – 255 characters

ccustemail

customer email [only populated for vendor]

1 – 255 characters

ccustfirstname

customer's first name [only populated for vendor]

1 - 255 characters

ccustfullname

customer name as typed in on the order form [only populated for vendor]

1 – 510 characters

ccustlastname

customer's last name [only populated for vendor]

 

1 – 255 characters

ccustshippingcountry

ship-to country [only populated for vendor]

0 – 255 characters

ccustshippingzip

ship-to zip code [only populated for vendor]

0 – 255 characters

ccuststate

customer state/province [only populated for vendor]

0 – 2 characters

ccustzip

customer zip code [only populated for vendor]

0 – 16 characters

cfuturepayments

Number of payments remaining [only populated for recurring products]

1 – 3 characters

cnextpaymentdate

Date of next payment (epoch time) [only populated for recurring products]

8 characters

corderamount

Order total amount (in pennies (1000 = $10.00))

3 – 10 characters

cprocessedpayments

Number of recurring payments made [only populated for recurring products]

1 – 3 characters

cproditem

product item sku

1 – 10 characters

cprodtitle

product title

0 – 255 characters

cprodtype

product type (STANDARD, RECURRING) [will also have 'Physical' if the product was a physical good]

8 – 11 characters

crebillamnt

Recurring payment amount (in pennies (1000 = $10.00)) [only populated for recurring products]

3 – 10 characters

crebillstatus

Status of subscription (empty, ACTIVE, COMPLETED, or CANCELED) [only populated for recurring products]

5 – 9 characters

ctid

tracking id for the recipient of the notification [only sent to vendor and affiliate, not JV partners]

0 – 24 characters

ctransaction*

transaction type (SALE, JV_SALE, INSF, RFND, CGBK, BILL, JV_BILL, TEST_SALE, TEST_JV_SALE, TEST_BILL, TEST_JV_BILL, TEST_RFND)         

4 – 15 characters

ctransaffiliate

affiliate nickname

0 – 10 characters

ctranspaymentmethod

payment method (AMEX, AUST, BLME, DISC, DNRS, ELV, ENRT, IMAS, JCBC, MAES, MSTR, PYPL, STVA, SWIT, TEST, VISA)

0 – 4 characters

ctranspublisher

vendor nickname

5 – 10 characters

ctransreceipt

receipt number

8 – 13 characters

ctransrole

Recipient's role in the transaction (AFFILIATE, VENDOR)

6 – 9 characters

ctranstime**

the Epoch time the transaction occurred (not included in cverify)

10 characters

cupsellreceipt**§

if this transaction is part of an upsell, this is the originating receipt number.

 

8 – 13 characters

cvendthru

download URL [only populated for vendor]

0 – 124 characters

cverify**

the "cverify" parameter is used to verify the validity of the previous fields

8 characters

Version 2.1

Identical to version 2 but adds the following field:

Parameter

Description

Details

ccustshippingstate

ship-to state/province [only populated for vendor]

0 – 255 characters

Version 4

Identical to version 2.1 with the following changes:

Parameter

Description

Details

cnoticeversion

Version of the notification

0 – 5 characters

ctransvendor

vendor nickname (we renamed ctranspublisher)

5 – 10 characters

crebillfrequency

frequency of the subscription (weekly, biweekly, monthly, quarterly, yearly)

0 – 255 characters

cbfid

ID of the upsell flow [only populated for vendor]

0 – 11 characters

cbf

upsell flow session [only populated for vendor]

0 – 16 characters

cbfpath

upsell flow path (shows the progress of the upsell flow and the result of each step) [only populated for vendor]

0 – 12 characters

corderlanguage

the language select by the customer on the order form [only populated for vendor]

0 – 2 characters

ctaxamount

tax amount paid by the customer (in pennies (1000 = $10.00)) [only populated for vendor]

3 – 10 characters

cshippingamount

amount of shipping and handling charged (in pennies (1000 = $10.00)) [only populated for vendor]

3 – 10 characters

Legacy Code Samples

Java

The following Java code will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key.

Note – This requires the jakarta commons codec library to be functional.

public static boolean ipnValid(HttpServletRequest request) {
        String secretKey = "YOUR SECRET KEY";
        List ipnFields = new ArrayList();
        @SuppressWarnings("rawtypes")
        Enumeration params = request.getParameterNames();
        while (params.hasMoreElements()) {
            String param = (String) params.nextElement();
            // cverify is computed by all POST parameters so any get parameters
            // on the notification url should be skipped as well.
            if (param.equals("cverify")) {
                continue;
            }
            ipnFields.add(param);
        }
        Collections.sort(ipnFields);
        StringBuilder pop = new StringBuilder();
        for (String field : ipnFields) {
            pop.append(request.getParameter(field));
            pop.append("|");
        }
        pop.append(secretKey);
        String expectedCVerify = DigestUtils.shaHex(pop.toString().getBytes("UTF-8")).substring(0, 8);
        return expectedCVerify.equalsIgnoreCase(request.getParameter("cverify"));
    }

PHP

The following PHP will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key (e.g. not URL-encoded).

Response Types:

1 = Pass
0 = Fail

<?php
 
function ipnVerification() {
    $secretKey="YOUR SECRET KEY";
    $pop = "";
    $ipnFields = array();
    foreach ($_POST as $key => $value) {
        if ($key == "cverify") {
            continue;
        }
        $ipnFields[] = $key;
    }
    sort($ipnFields);
    foreach ($ipnFields 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 = sha1(mb_convert_encoding($pop, "UTF-8"));
    $calcedVerify = strtoupper(substr($calcedVerify,0,8));
    return $calcedVerify == $_POST["cverify"];
}
 
?>

C#

The following C# will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key (e.g. not URL-encoded).

///
/// This method takes the same named post parameters that are sent in the ClickBank Instant Notification Service.
/// True if the ClickBank passed paramter cverify matches the calculated sha1 of the provided data, False otherwise
///
    public static bool ipnValid(HttpRequest request)
    {
        string secretKey = "YOUR SECRET KEY";
        List ipnFields = new List();
        foreach(string param in request.Form.Keys) {
            if (param.Equals("cverify")) {
                continue;
            }
            ipnFields.Add(param);
        }
        ipnFields.Sort();
        string pop = "";
        foreach(String field in ipnFields) {
            pop += request.Form.Get(field) + "|";
        }
        pop += secretKey;
        string cverify = request.Form.Get("cverify");
        byte[] hashedData = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(pop));
        string calced_verification = BitConverter.ToString(hashedData).Replace("-", "").ToUpper().Substring(0, 8);
        return calced_verification.Equals(cverify);
    }

Python

The following Python will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key (e.g. not URL-encoded).

#!/usr/bin/env python -tt
 
import hashlib
 
##
# Verify cverify from an ipn.
# @param post_params: A dictionary of all POST parameters from the notification
# @return: True if the cverify parameter is valid, false otherwise
def ipnVerification(post_params):
    secret_key = "YOUR SECRET KEY"
    pop = ""
    ipn_fields = []
    for key in post_params.keys():
        if key == "cverify":
            continue
        ipn_fields.append(key)
    ipn_fields.sort()
    for field in ipn_fields:
        pop += post_params[field] + "|"
    pop += secret_key
    return post_params["cverify"] == hashlib.sha1(pop).hexdigest()[:8].upper()

Ruby

The following Ruby will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key (e.g. not URL-encoded).

#!/usr/bin/env ruby
 
require 'digest/sha1'
 
# Verify cverify from an ipn.  post_params is a Hash of all
# POST parameters from the ipn.
def ipnVerification(post_params)
  secret_key = "YOUR SECRET KEY"
  pop = ""
  ipn_fields = []
  post_params.each_key do |key|
    if key == "cverify"
        next
    end
    ipn_fields &lt;&lt; key
  end
  ipn_fields.sort
  ipn_fields.each do |field|
    pop += post_params[field] + "|"
  end
  pop += secret_key
  calced_verification = Digest::SHA1.hexdigest(pop).upcase[0,8]
  return calced_verification == post_params["cverify"]
end

VB.net

The following VB.net will create the cverify value and verify if it is correct using the plain text values in the HTTP POST and your secret key (e.g. not URL-encoded).

public Function ipnVerification(request as HttpRequest)

Dim secretKey as String = "YOUR SECRET KEY"
Dim ipnFields as New List()
Dim sha As New SHA1CryptoServiceProvider()

For Each param In request.Form.Keys()
if param.Equals("cverify") then Continue For
      ipnFields.Add(param)
Next
  
ipnFields.Sort()
Dim pop as String = ""

For Each field in ipnFields
pop += request.Form.Get(field) + "|"
Next

pop += secretKey

Dim result() As Byte = sha.ComputeHash(New System.Text.ASCIIEncoding().GetBytes(pop))
Dim calced_verification As String = BitConverter.ToString(result).Replace("-",
"").ToUpper().Substring(0, 8)
Return calced_verification.Equals(cverify)

End Function

 

 
Topic is closed for comments