<?php

//replace merchant id and password with values provided to you by FAC Support
define(‘MerchantId’, ‘88803618’); //FACID
define(‘ProcessingPassword’, ‘TtfBJw9D’);

//replace the value with your HTTPS URL; required by Authorize3DS and HPP
define(‘MerchantResponseUrl’, ‘https://crinci.cr/test’);

//do not change
define(‘AcquirerId’, ‘464748’);
define(‘DefaulSignatureMethod’, ‘SHA1’);
define(‘FacDefaultNamespace’, ‘http://schemas.firstatlanticcommerce.com/gateway/data’);
define(‘DefaultNamespaces’, ‘xmlns:i=”http://www.w3.org/2001/XMLSchema-instance” xmlns=”‘ .FacDefaultNamespace .'”‘);

//FAC service URLs
define(‘XMLBaseUrl’, ‘https://ecm.firstatlanticcommerce.com/PGServiceXML’);

//request templates
/* There is an inconsistency in naming you should be aware of:
* some of the requests use MerchantNumber for FACID, while some use MerchantId.
*
* Also some calls require a signature, while some calls require just processing password
*/

define(‘TokenizeRequestTemplate’, ‘
<TokenizeRequest %s >
<MerchantNumber>%s</MerchantNumber>
<Signature>%s</Signature >
<CardNumber>%s</CardNumber>
<ExpiryDate>%s</ExpiryDate>
<CustomerReference>%s</CustomerReference>
</TokenizeRequest>
‘);

define(‘DetokenizeRequestTemplate’, ‘
<DeTokenizeRequest %s >
<MerchantNumber>%s</MerchantNumber>
<Signature>%s</Signature >
<TokenPAN>%s</TokenPAN>
</DeTokenizeRequest>
‘);

define(‘UpdateTokenRequestTemplate’, ‘
<UpdateTokenRequest %s >
<MerchantNumber>%s</MerchantNumber>
<Signature>%s</Signature >
<TokenPAN>%s</TokenPAN>
<ExpiryDate>%s</ExpiryDate>
<CustomerReference>%s</CustomerReference>
</UpdateTokenRequest>
‘);

define(‘ExpiringCardsRequestTemplate’,’
<ExpiringCreditCardsRequest %s >
<MerchantId>%s</MerchantId>
<Signature>%s</Signature >
<StartDate>%s</StartDate>
<EndDate>%s</EndDate>
</ExpiringCreditCardsRequest>
‘);

define(‘TransactionStatusRequestTemplate’, ‘
<TransactionStatusRequest %s >
<AcquirerId>%s</AcquirerId>
<MerchantId>%s</MerchantId>
<Password>%s</Password>
<OrderNumber>%s</OrderNumber>
</TransactionStatusRequest>
‘);

define(‘TransactionModificationRequestTemplate’, ‘
<TransactionModificationRequest %s >
<AcquirerId>%s</AcquirerId>
<MerchantId>%s</MerchantId>
<Password>%s</Password>
<OrderNumber>%s</OrderNumber>
<ModificationType>%s</ModificationType>
<Amount>%s</Amount>
<CurrencyExponent>%s</CurrencyExponent>
</TransactionModificationRequest>
‘);

define(‘TransactionDetailsTemplate’, ‘
<TransactionDetails>
<AcquirerId>%s</AcquirerId>
<MerchantId>%s</MerchantId>
<Signature>%s</Signature>
<SignatureMethod>%s</SignatureMethod>
<TransactionCode>%s</TransactionCode>
<OrderNumber>%s</OrderNumber>
<Amount>%s</Amount>
<Currency>%s</Currency>
<CurrencyExponent>%s</CurrencyExponent>
<CustomerReference>%s</CustomerReference>
<IPAddress>127.0.0.1</IPAddress>
<CustomData />
<ExtensionData />
</TransactionDetails>
‘);

define(‘CardDetailsTemplate’, ‘
<CardDetails>
<CardNumber>%s</CardNumber>
<CardExpiryDate>%s</CardExpiryDate>
<CardCVV2>%s</CardCVV2>
<Installments>%s</Installments>
<DocumentNumber>%s</DocumentNumber>
</CardDetails>
‘);

define(‘ShippingDetailsTemplate’, ‘
<ShippingDetails>
<ShipToFirstName>%s</ShipToFirstName>
<ShipToLastName>%s</ShipToLastName>
<ShipToAddress>%s</ShipToAddress>
<ShipToAddress2>%s</ShipToAddress2>
<ShipToCity>%s</ShipToCity>
<ShipToState>%s</ShipToState>
<ShipToZipPostCode>%s</ShipToZipPostCode>
<ShipToCountry>%s</ShipToCountry>
<ShipToTelephone>%s</ShipToTelephone>
<ShipToEmail>%s</ShipToEmail>
</ShippingDetails>
‘);

define(‘AuthorizeRequestTemplate’, ‘
<AuthorizeRequest %s >
%s%s%s
</AuthorizeRequest>
‘);

define(‘Authorize3DSRequestTemplate’, ‘
<Authorize3DSRequest %s >
%s%s%s
<MerchantResponseURL>%s</MerchantResponseURL>
</Authorize3DSRequest>
‘);

define(‘HostedPagePreprocessRequest’, ‘
<HostedPagePreprocessRequest %s >
%s
<CardHolderResponseURL>%s</CardHolderResponseURL>
</HostedPagePreprocessRequest>
‘);

define(‘HPPResultsRequestTemplate’, ‘
<string %s>%s</string>
‘);
///For a given PAN creates token, or retrieves one if it already exists
function testTokenize()
{
$request = sprintf(TokenizeRequestTemplate,
DefaultNamespaces,
MerchantId,
generateTokenizeSignature(),
‘4242424242424242’, //PAN
‘1221’, //expiry date, MMYY
MerchantId .’ PHP test ‘ .date(“Y-m-d H:i:s”) //CustomerReference
);

try
{
$response = postXmlRequest(XMLBaseUrl .’\Tokenize’, $request);
echo print_r($response, true);

//parsing the response
$result = simplexml_load_string($response);
echo “\n\nToken: ” .$result->Token;
}
catch (Exception $e)
{
echo $e;
}
}

///For a given token retrieves PAN
function testDetokenize()
{
$request = sprintf(DetokenizeRequestTemplate,
DefaultNamespaces,
MerchantId,
generateTokenizeSignature(),
‘424242_04XOK4242′ //tokenized PAN
);

try
{
$response = postXmlRequest(XMLBaseUrl .’\DeTokenize’, $request);
echo print_r($response, true);
}
catch (Exception $e)
{
echo $e;
}
}

///Updates expiry date and customer reference for a given token.
///The token must exist
function testUpdateToken()
{
$request = sprintf(UpdateTokenRequestTemplate,
DefaultNamespaces,
MerchantId,
generateTokenizeSignature(),
‘424242_04XOK4242’, //tokenized PAN
‘1221’, //expiry date, MMYY
MerchantId .’ PHP test ‘ .date(“Y-m-d H:i:s”) //CustomerReference
);

try
{
$response = postXmlRequest(XMLBaseUrl .’\UpdateToken’, $request);
echo print_r($response, true);

//parsing the response
$result = simplexml_load_string($response);
echo “\n\nSuccess: ” .$result->Success;

}
catch (Exception $e)
{
echo $e;
}
}

///Selects cards with expiry date within a given range
function testExpiringCreditCards()
{
$request = sprintf(ExpiringCardsRequestTemplate,
DefaultNamespaces,
MerchantId,
generateTokenizeSignature(),
‘0100’, //from date, MMYY
‘1231’ //to date, MMYY
);

try
{
$response = postXmlRequest(XMLBaseUrl .’\ExpiringCreditCards’, $request);
echo print_r($response, true);
}
catch (Exception $e)
{
echo $e;
}
}

///Generates signature that can be used by tokenization calls
function generateTokenizeSignature()
{
$source = ProcessingPassword .MerchantId .AcquirerId;
$signature = base64_encode(sha1($source, true));
return $signature;
}

function generateFACPG2Signature($orderNo, $formattedAmount, $currency, $urlencode)
{
$source = ProcessingPassword .MerchantId .AcquirerId .$orderNo .$formattedAmount .$currency;
$signature = base64_encode(sha1($source, true));
return $urlencode ? urlencode($signature) : $signature;
}

function AmountFormatted($amount, $currencyExponent)
{
return str_pad(”.($amount * pow(10, $currencyExponent)), 12, “0”, STR_PAD_LEFT);
}

function getTransactionDetails($transactionCode, $orderNo, $formattedAmount, $currency, $currencyExponent, $urlencode)
{
return sprintf(TransactionDetailsTemplate,
AcquirerId,
MerchantId,
generateFACPG2Signature($orderNo, $formattedAmount, $currency, $urlencode),
DefaulSignatureMethod,
$transactionCode,
$orderNo,
$formattedAmount,
$currency,
$currencyExponent,
MerchantId .’ PHP test ‘ .date(“Y-m-d H:i:s”), //CustomerReference
‘127.0.0.1’ //IPAddress
);
}

function getCardDetails($orderNo)
{
return sprintf(CardDetailsTemplate,
‘4242424242424242’, //PAN
‘1221’, //expiry date, MMYY
‘234’, //CVV2
‘0’, //Installments
$orderNo //DocumentNumber
);
}

function getShippingDetails()
{
return sprintf(ShippingDetailsTemplate,
‘John’,
‘Smith’,
‘433 W Harrison St’,
‘Fl Lbby’,
‘Chicago’,
‘IL’,
‘60699’,
‘840’, //ISO country code = USA
‘+1 312-983-8130’,
‘john.smith@gmail.com’
);
}

function postXmlRequest($url, $data)
{
$options = array(
‘http’ => array(
‘header’ => “Content-type: application/x-www-form-urlencoded\r\n”,
‘method’ => ‘POST’,
‘content’ => $data
)
);

$context = stream_context_create($options);
return file_get_contents($url, false, $context);
}

function testAuthorize3DS()
{
$transactionCode = 0;
$orderNo = ‘ORD_’ .MerchantId .date(“Ymd_His”); //must be unique value

$currency = ‘188’; //USD
$currencyExponent = 2;

$formattedAmount = AmountFormatted(1.01, $currencyExponent);

$request = sprintf(Authorize3DSRequestTemplate,
DefaultNamespaces,
getTransactionDetails($transactionCode, $orderNo, $formattedAmount, $currency, $currencyExponent, false),
getCardDetails($orderNo),
getShippingDetails(),
MerchantResponseUrl
);

try
{
$response = postXmlRequest(XMLBaseUrl .’\Authorize3DS’, $request);
echo print_r($response, true);

/* To complete a Auth3DS transaction, post the response.HTMLFormData, unaltered, back to cardholder’s browser.
*
* Example:
* Response.Clear();
* Response.Write( [unaltered response] );
* Response.End();
*
* Final 3DS auth data will be sent to your MerchantResponseURL
*/

//parsing the response
$result = simplexml_load_string($response);
echo “\n\nResult: ” .$result->ResponseCodeDescription;
}
catch (Exception $e)
{
echo $e;
}
}

testAuthorize3DS();
?>