Accepting payments using Verisign's Payflow Pro
Intended Audience
Accepting Payments Online
Prerequisites
Payment Gateways
Creating Payment Transactions
Creating Transaction Types and Parameters
Using PHP Payflow Pro (pfpro) extension
Transaction Example 1: Sale
Using Transaction Response
Transaction Example 2: Capture a previous Authorization
Class Encapsulation
Main OOP Principles:
Encapsulation Principles:
Possible Additions
The Script
About the Author
Intended Audience
This tutorial is intended for the developer interested in accepting and managing payments online using the PHP Payflow Pro (pfpro) extension and applying basic class encapsulation principles to form an independent, easy to maintain library.Accepting Payments Online
Accepting payment in real time is now an integral part of e-commerce and is one of the basic building blocks of an online business. There are many companies offering payment gateways and your or your client's choice largely depends on location, transaction volume, your bank's partners etc.This Tutorial concentrates on PHP's Payflow Pro extension, which allows you to carry out seamless transactions with Verisign. However, the principles discussed in this tutorial can be easily applied to PHP's other payment extensions such as the CyberMUT extension and general functionality encapsulation into independent libraries.
Prerequisites
You will need to have the Payflow Pro (pfpro) extension compiled and enabled. In order to install the pfpro extension, you need to download the appropriate SDK for your platform from the Verisign Payment Manager (https://manager.verisign.com) and configure PHP with--with-pfpro. More
information about installation can be found at
http://www.php.net/pfpro.You will need a test account from Verisign. You can request a 30 day trial from Verisign at http://www.verisign.com.
Payment Gateways
A payment gateway acts as a "middleman" between your website and the Credit Card Processing Network or Clearing Houses. Payment gateways are directly networked to the banks and financial networks allowing them to verify in real time whether a submitted credit card is valid and if there are available funds in the account. They then return the transaction results to your program.Payment gateways usually have a management console allowing you to view, manage and generate reports on transactions, and include various other tools and utilities.
Verisign's Payflow Pro is an API directly to Verisign allowing you to fully customize the shopping experience and hence eliminate the need to re-direct customers to a different site to accept payments.
Payment gateways work like this:

Creating Payment Transactions
Creating Transaction Types and Parameters
When using credit cards to pay online, there are 5 common transactions. These (and more) are available using the Payflow Pro system. It is recommended that you use the Payflow Pro developer's Guide available from the Verisign Payment Manager (https://manager.verisign.com/) when creating transaction types.The basic transactions are:
- Sale – Authorize and Capture a sale. This will request the funds from the customer. This is suitable for sales where you intend to deliver the item immediately (such as downloads, or where items are shipped directly).
- Authorize (Pre-Auth) – authorize a payment for later capture. This is suitable for situations where it takes a while for items to ship.
- Capture – request the funds for a previous Authorize request.
- Void – cancel a transaction.
- Credit – refund a whole or partial transaction.
- Sale, Authorize – credit card number, expiration date and amount.
- Capture, Void – PNREF. (This is the unique ID for each transaction that Verisign uses.) See Transaction Example 2 below.
- Credit – PNREF. If you wish to credit an amount different to the original sale price you also need the Amount to credit.
Using PHP Payflow Pro (pfpro) extension
The pfpro extension allows you to directly communicate with the Verisign payment gateway using the pfpro functions.The pfpro extension has 3 basic functions:
pfpro_init()– initialize the pfpro transactionpfpro_process()– process the transaction. This function accepts the transaction type, amount, server address etc.pfpro_cleanup()– cleanup the transaction once you are done.
pfpro_init()
and pfpro_cleanup() since the extension
does so automatically when necessary. The functions are available for cases
where you wish to perform a number of transactions together and hence require
exact control over each sub-transaction.
Let's take a look at
pfpro_process() and its
parameters.array pfpro_process ( array
parameters [, string address [, int port [, int timeout [, string proxy address
[, int proxy port [, string proxy logon [, string proxy
password]]]]]]])Returns: An associative array
containing the responseThe address, port, timeout and other parameters can be set using the php.ini file. The default server for test transactions is test-payflow.Verisign.com. For live transactions it is payflow.verisign.com. See http://www.php.net/pfpro for possible php.ini settings.
The main input of interest is the parameters argument. This is an associative array of the transaction type and required information (as laid out above).
To best understand how to set up the transaction parameters array, try this simple example.
Transaction Example 1: Sale
The simplest transaction type is Sale where you request and settle funds in real time using a credit card.Looking at the Payflow Pro Developer's Guide, you can see that the information required for setting up a Sale transaction is as follows:
$transaction = array('USER' => 'mylogin', // username
'PWD' => 'mypassword', // password
'PARTNER' => 'VeriSign', // Partner
'TRXTYPE' => 'S', // Type Sale
'TENDER' => 'C', // Credit Card
'AMT' => 1.50, // Amount to charge
'ACCT' => '4111111111111111',// CC #
'EXPDATE' => '0904' // Expiry (MMYY)
);
Once the transaction is formed, you can send it to Verisign:
pfpro_init();
$result = pfpro_process($transaction);
pfpro_cleanup();
$result will
contain the results from Verisign in an associative array.Using Transaction Response
Take a closer look at the result ($result):
print_r ($result);
// Results are:
Array
(
[RESULT] => 0
[PNREF] => V64E29954472
[RESPMSG] => Approved
[AUTHCODE] => 010101
)
- $result['RESULT'] of 0 means that the transaction was successful. Refer to the Payflow Pro Developer's Guide for all possible return codes and their meanings.
- $result['PNREF'] is the unique Reference ID that Verisign uses to index transactions. You must store this for future reference (CHAR(12)).
- $result['RESPMSG'] is the Verisign response message. Any success or error messages will be present here.
- $result['AUTHCODE'] is the authcode returned from Verisign. It is recommended that you store this information for future use (CHAR(6)).
$result['RESULTS'] == 0 indicates
successful transactions, you can extend the code as follows:
pfpro_init();
$result = pfpro_process($transaction);
pfpro_cleanup();
if ($result['RESULT'] == 0) {
// Complete transaction and log returned data.
print 'Success';
} else {
print "Error with payment:\n";
print $result['RESPMSG']; // Log error and try again.
}
$result array. The RESULT parameter
of the array ($result['RESULT']) returned
by Verisign indicates the transaction outcome (success, failure, duplicate transaction
etc.).Transaction Example 2: Capture a previous Authorization
When capturing a previous Authorization request, use the PNREF returned in the$result Array as the
'ORIGID' parameter in order to complete the transaction.The transaction now becomes:
$transaction = array('USER' => 'mylogin',
'PWD' => 'mypassword',
'PARTNER' => 'VeriSign',
'TRXTYPE' => 'D', // Delayed Capture
'TENDER' => 'C',
'ORIGID' => 'ABC123456789'
Class Encapsulation
Now that you know the basics of using the Payflow Pro extension and setting up transaction types, you might ask "How can I make a library that will allow me to capture all of the functionality I require in one central easily maintained library?" The answer is quite simple – use OOP (Object Oriented Programming) Class Encapsulation principles.Main OOP Principles:
The 3 main OO Principles are:- Encapsulation – This refers to the concept of making an object a "Black Box". You don't need to know how the internals work; you only need to know the desired input and output. This means the object includes everything it needs to carry out the desired functionality, in terms of properties (variables or data types) and methods (functions that operate on these variables). In order to operate the object, you expose certain methods (functions) to the outside world.
- Inheritance – This refers to the ability to extend classes to form additional functionality in the Child Class.
- Polymorphism – This is the most complicated part of OO Design principles and refers to the concept that every class should handle all data types. You shouldn't create different classes to handle different data types.
Encapsulation Principles
You have already determined that the class is going to deal with online payments using the pfpro extension.Classes are made up of Properties (variables) and Methods (functions that operate on the data types). In order to determine the structure of your class, you can analyze your requirements by asking 2 simple questions:
- "What functions do I need the object to perform?"
- "What information do I need to store in the object in order to facilitate the required functionality?"
Functionality Required:
- Create immediate sales.
- Create Authorizations for later capture.
- Capture previous Authorization request.
- Credit a transaction
- Cancel (void) a transaction
- Store requested transaction.
- Store the response.
- Store additional (optional) information (server address, port, proxy information)
Here’s the Class skeleton:
class pfpro {
var $transaction;// transaction input array
var $result; // transaction response array
/* Constructor - used to generate common transaction
entries (such as username, password and partner) */
function pfpro() {}
function sale() {}
function authorize() {}
function capture() {}
function credit() {}
function cancel() {}
// process payment and store results
function process() {}
}
// Constructor - common transaction information
function pfpro($user, $pwd, $partner = "VeriSign") {
$this->transaction = Array();
$this->result = Array();
// We always need to send username, password & partner
$this->transaction['USER'] = $user;
$this->transaction['PWD'] = $pwd;
$this->transaction['PARTNER'] = $partner;
// Can add optional server and proxy information
}
function sale($amount, $card_no, $exp_month, $exp_year) {
$this->transaction['ACCT'] = ereg_replace("[^0-9]" ,"" ,$card_no);
$this->transaction['AMT'] = sprintf("%.2f", $amount);
}
/* In cases where an input is optional, we can use the function's Default argument values. Remember to list the Defaulted variables on the right hand side of the non-defaulted (required) variables.
For example, when issuing a capture, the Amount is optional and only supplied when we wish to capture a lower or higher amount than originally requested. */
function capture($PNREF, $amount = "") {
$this->transaction['ORIGID'] = trim($PNREF);
if ($amount != "") {
$this->transaction['AMT'] = sprintf("%.2f",$amount);
}
}
$this->result.
function process() {
pfpro_init();
$this->result = pfpro_process($this->transaction);
pfpro_cleanup();
}
Possible Additions
From here, you can go in many directions. A few possibilities may be:- Using Verisign's Recurring Billing for payment automation. This is ideal for subscription based services or payment plans.
- Extending functions to deal with online check payments.
- Using Address Verification System (AVS) for US based credit cards. This allows verification of the card owner's address and zip code to minimize fraudulent transactions.
- Adding order comments. These are passed to Verisign along with the order and can be recalled later from the Verisign Payment Manager.
- Storing transaction results in a database or file. It is recommended that you store, at minimum, the order date and time, PNREF, AUTHCODE and your purchase ID or Order Number. Refer to the Payflow Pro Developer Guide for information about which items are required for future reference.

Comments
The mentioned SDK in this article is not available now.
I entered to https://manager.verisign.com
and I didn't found it.
Do you know where I can found it now?
Thanks.
http://www.verisign.com/verisign-inc/news-and-events/news-archive/us-news-2005/page_035983.html