home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 August
/
PCWorld_2001-08_cd.bin
/
Komunikace
/
phptriad
/
phptriadsetup2-11.exe
/
php
/
pear
/
Payment
/
Verisign.php
Wrap
PHP Script
|
2001-01-10
|
17KB
|
543 lines
<?php /* -*- C++ -*- */
/*
+----------------------------------------------------------------------+
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2001 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: David Croft: <david@infotrek.co.uk> |
+----------------------------------------------------------------------+
*/
/* $Id: Verisign.php,v 1.3 2001/01/10 01:01:58 ssb Exp $ */
/* ******** NOTICE ********
*
* This code is completely untested. Do not use it!
* It is here for peer review. It will undergo revision, bugfixes
* and probably API changes. It must not be used yet!
*/
/* Verisign Payment Processing class.
*
* Some test cards:
* Amex: 378282246310005
* Discover: 6011111111111117
* Mastercard: 5105105105105100 or 5555555555551111
* Visa: 4242424242424242 or 4111111111111111
*/
require_once 'PEAR.php';
/* Symbolic names for decoded response codes */
/* We want as few of these as possible so calling code has fewer branches */
define("VERISIGN_SUCCESS", 0);
/* 10+ - user errors */
define("VERISIGN_BAD_CARD", 10);
define("VERISIGN_INVALID_EXPIRY", 11);
define("VERSIGIN_BAD_CARD_TYPE", 12);
/* 20+ - our errors */
define("VERISIGN_CONFIG_ERROR", 20);
define("VERISIGN_UNRECOGNISED_RESPONSE", 21);
/* 30+ - temporary errors, try again later */
define("VERISIGN_TEMPORARY_ERROR", 30);
define("VERISIGN_REFERRAL", 31);
class Payment_Verisign
{
/* These are all private variables. DO NOT ACCESS THEM DIRECTLY. */
/* There are specific functions to set each of these */
var $hostaddress = 'test.signio.com';
var $hostport = 443;
var $timeout = 30;
var $proxyaddress;
var $proxyport;
var $proxylogon;
var $proxypassword;
var $username;
var $password;
var $cardnumber;
var $expiredate;
var $params = array();
function Payment_Verisign()
{
/* can you return stuff from a constructor? */
if (!extension_loaded('pfpro')) {
return new VerisignException('Payflow Pro module is not compiled into PHP. Compile PHP using --with-pfpro.');
}
}
function set_host($hostaddress, $hostport = 443)
{
if (!$hostaddress or !strlen($hostaddress)) {
return new VerisignException('Invalid host address');
}
if (!$hostport or $hostport < 1) {
return new VerisignException('Invalid host port');
}
$this->hostaddress = $hostaddress;
$this->hostport = $hostport;
}
function set_timeout($timeout)
{
if ($timeout < 1 or $timeout > 3600) {
return new VerisignException('Invalid timeout value');
}
$this->timeout = $timeout;
}
function set_logon($username, $password)
{
if (!$username or !strlen($username)) {
return new VerisignException('Invalid user name');
}
if (!$password or !strlen($password)) {
return new VerisignException('Invalid password');
}
$this->username = $username;
$this->password = $password;
}
function set_proxy($proxyaddress, $proxyport = 443, $proxylogon = '', $proxypassword = '')
{
if (!$proxyaddress or !strlen($proxyaddress)) {
return new VerisignException('Invalid proxy address');
}
if (!$proxyport or $proxyport < 1) {
return new VerisignException('Invalid proxy port');
}
$this->proxyaddress = $proxyaddress;
$this->proxyport = $proxyport;
if ($proxylogon and strlen($proxylogon)) {
$this->proxypassword = $proxylogon;
}
if ($proxylogon and strlen($proxypassword)) {
$this->proxypassword = $proxypassword;
}
}
function set_card($cardnumber, $expiremonth, $expireyear)
{
$this->cardnumber = $cardnumber;
if ($expiremonth < 1 or $expiremonth > 12) {
return new VerisignException('Invalid expiry month');
}
if (($expireyear > 99 and $expireyear < 2000) or $expireyear > 2100) {
return new VerisignException('Invalid expiry year');
}
$this->expiredate = sprintf("%02d%02d", $expiremonth, ($expireyear > 100) ? ($expireyear % 100) : $expireyear);
}
function set_avs($street, $zip)
{
if (!$street or !is_string($street) or !strlen($street)) {
return new VerisignException('AVS Street was not specified or was not a string');
}
if (!$zip or !is_string($zip) or !strlen($zip)) {
return new VerisignException('AVS Zip was not specified or was not a string');
}
$this->params['STREET'] = $street;
$this->params['ZIP'] = $zip;
}
function add_parameter($key, $value)
{
if (!$key or !is_string($key) or !strlen($key)) {
return new VerisignException('Key must be a string');
}
$this->params[$key] = $value;
}
function add_parameters($newparams)
{
foreach ($newparams as $key => $value) {
if (!$key or !is_string($key) or !strlen($key)) {
return new VerisignException('Keys must be strings');
}
}
$this->params = array_merge($this->params, $newparams);
}
function reset_parameters()
{
$this->params = array();
}
function set_comment1($comment)
{
$this->params['COMMENT1'] = $comment;
}
function set_comment2($comment)
{
$this->params['COMMENT2'] = $comment;
}
/* Functions to process transactions */
/* sale: authorise and immediate capture */
function sale($amount)
{
if (!$amount or $amount <= 0) {
return new VerisignException('You cannot perform a sale on a negative or zero amount');
}
$this->params['AMT'] = number_format($amount, 2, '.', '');
return $this->process('S');
}
/* authorise: authorise only for capture later with capture() */
function authorize($amount)
{
/* for the yanks */
return $this->authorise($amount);
}
function authorise($amount)
{
if (!$amount or $amount <= 0) {
return new VerisignException('You cannot perform an authorisation on a negative or zero amount');
}
$this->params['AMT'] = number_format($amount, 2, '.', '');
return $this->process('A');
}
/* capture: capture an authorised transaction */
function capture($origid)
{
if (!$origid or !strlen($origid)) {
return new VerisignException('You must provide the original PNREF id for a delayed capture');
}
$this->params['ORIGID'] = $origid;
return $this->process('D');
}
/* refund: give money back (ouch) */
function refund($amount)
{
if (!$amount or $amount <= 0) {
return new VerisignException('You cannot perform an authorisation on a negative or zero amount');
}
$this->params['AMT'] = number_format($amount, 2, '.', '');
return $this->process('C');
}
/* refund_transaction: refund a specific earlier transaction - no card required */
function refund_transaction($origid)
{
if (!$origid or !strlen($origid)) {
return new VerisignException('You must provide the original PNREF id for a transaction refund');
}
$this->params['ORIGID'] = $origid;
return $this->process('C');
}
/* voice_auth: voice authorised transaction */
function voice_auth($amount, $authcode)
{
if (!$amount or $amount <= 0) {
return new VerisignException('You cannot perform an authorisation on a negative or zero amount');
}
if (!$authcode or !strlen($authcode)) {
return new VerisignException('You must provide an authcode for a voice authorisation');
}
$this->params['AMT'] = number_format($amount, 2, '.', '');
$this->params['AUTHCODE'] = $authcode;
return $this->process('F');
}
function void($origid)
{
if (!$origid or !strlen($origid)) {
return new VerisignException('You must provide the original PNREF id for a transaction refund');
}
$this->params['ORIGID'] = $origid;
return $this->process('V');
}
/* Central processing function */
function process($trxtype, $tender = 'C')
{
if (!extension_loaded('pfpro')) {
return new VerisignException('Payflow Pro module is not compiled into PHP. Compile PHP using --with-pfpro.');
}
if (!$this->params['USER']) {
if ($this->username and strlen($this->username)) {
$this->params['USER'] = $this->username;
}
else {
return new VerisignException('You have not specified the Verisign user name');
}
}
if (!$this->params['PWD']) {
if ($this->password and strlen($this->password)) {
$this->params['PWD'] = $this->username;
}
else {
return new VerisignException('You have not specified the Verisign password');
}
}
if (!$this->params['ACCT']) {
if ($this->cardnumber and strlen($this->cardnumer)) {
$this->params['ACCT'] = $this->cardnumber;
}
else if ($this->params['ORIGID'] and
($trxtype == 'C' or $trxtype == 'D' or $trxtype == 'V')) {
/* don't need card number if we're crediting or capturing
* or voiding a specific transaction */
}
else {
return new VerisignException('You have not specified the card number');
}
}
if (!$this->params['EXPDATE']) {
if ($this->expiredate and strlen($this->expiredate)) {
$this->params['EXPDATE'] = $this->expiredate;
}
else if ($this->params['ORIGID'] and
($trxtype == 'C' or $trxtype == 'D' or $trxtype == 'V')) {
/* don't need expiry date if we're crediting or capturing
* or voiding a specific transaction */
}
else {
return new VerisignException('You have not specified the expiry date');
}
}
if (!$trxtype or !strlen($trxtype)) {
return new VerisignException('Invalid transaction type');
}
$this->params['TRXTYPE'] = $trxtype;
if (!$tender or !strlen($tender)) {
return new VerisignException('Invalid tender');
}
$this->params['TENDER'] = $tender;
/* Some final validation of our member variables */
if (!$this->hostaddress or !strlen($this->hostaddress)) {
return new VerisignException('No host address specified');
}
if (!$this->hostport or $this->hostport < 1) {
return new VerisignException('No host port specified');
}
/* Now process it */
if ($this->proxypassword and strlen($this->proxypassword)) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport, $this->timeout, $this->proxyaddress, $this->proxyport, $this->proxylogon, $this->proxypassword);
}
else if ($this->proxylogon and strlen($this->proxylogon)) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport, $this->timeout, $this->proxyaddress, $this->proxyport, $this->proxylogon);
}
else if ($this->proxyport and $this->proxyport > 0) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport, $this->timeout, $this->proxyaddress, $this->proxyport);
}
else if ($this->proxyaddress and strlen($this->proxyaddress)) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport, $this->timeout, $this->proxyaddress);
}
else if ($this->timeout and $this->timeout > 0) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport, $this->timeout);
}
else if ($this->hostport and $this->hostport > 0) {
$response = pfpro_process($this->params, $this->hostaddress, $this->hostport);
}
else if ($this->hostaddress and ($this->hostaddress)) {
$response = pfpro_process($this->params, $this->hostaddress);
}
else {
$response = pfpro_process($this->params);
}
if (!$response) {
return new VerisignException('No response received from Payflow Pro!');
}
if (!$response['RESULT']) {
$response['RESULT'] = -999;
}
return $response;
}
/* Decode the myriad of Verisign response codes into a meaningful few */
function decode_response($code)
{
if (is_array($code)) {
$code = $code['RESULT'];
}
else if (!is_integer($code)) {
return new VerisignException('Result code must be an integer');
}
switch ($code) {
case 0: /* Approved */
return VERISIGN_SUCCESS;
case 12: /* Declined */
case 23: /* Invalid account number */
case 50: /* Insufficient funds available */
case 112: /* Failed AVS check */
return VERISIGN_BAD_CARD;
case 24: /* Invalid expiry date */
return VERISIGN_INVALID_EXPIRY;
case 2: /* Invalid tender */
return VERISIGN_BAD_CARD_TYPE;
case 1: /* User authentication failed */
case 3: /* Invalid transaction type */
case 4: /* Invalid amount */
case 5: /* Invalid merchant information */
case 7: /* Field format error */
case 19: /* Original transaction ID not found */
case 20: /* Cannot find the customer reference number */
case 22: /* Invalid ABA number */
case 25: /* Transaction type not mapped to this host */
case 100: /* Invalid transaction returned from host */
case 105: /* Credit error */
case 108: /* Void error */
case 111: /* Capture error */
case 113: /* Cannot exceed sales cap */
return VERISIGN_CONFIG_ERROR;
case 11: /* Client timeout waiting for response */
case 101: /* Timeout value too small */
case 102: /* Host unavailable */
case 103: /* Error reading response from host */
case 104: /* Tiemout waiting for host response */
case -1: /* Server socket unavailable */
case -2: /* Hostname lookup failed */
case -3: /* Client time out */
case -4: /* Socket initialisation error */
case -5: /* SSL context initialisation failed */
case -6: /* SSL verification policy error */
case -7: /* SSL verify location error */
case -8: /* X509 certification verification error */
case -99: /* Internal error to the library */
case -999: /* Error from this class, no result found */
return VERISIGN_TEMPORARY_ERROR;
case 13: /* Referral */
return VERISIGN_REFERRAL;
}
/* 99: General error */
/* 1000: Generic host error */
/* and any others */
return VERISIGN_UNRECOGNISED_RESPONSE;
}
/*
* bool isError ($var)
* Determine whether or not a variable is a PEAR exception
*/
function isError ($var)
{
return (is_object ($var) and
substr (get_class ($var), -9) == 'Exception');
}
/*
* double Payment_Verisign_version(void)
* Returns the current Payment_Verisign version.
*/
function Payment_Verisign_version()
{
return (0.1);
}
}
class VerisignException extends PEAR_Error
{
var $classname = 'VerisignException';
var $error_message_prepend = 'Error in Payment_Verisign';
function VerisignException($message)
{
$this->PEAR_Error($message);
}
}
?>