Eksempel script til Betalings API

Nedenfor finder du kildekoden til et php script, der simulerer et betalingsflow gennem betalings API.

Læs dokumentationen til Betalings API her

Scriptet demonstrerer de grundlæggende principper som opsamling af variabler fra shoppen, hvordan man anvender checksumme og hvordan callbacks fungerer. Scripet er selvdokumenterende og på engelsk, så det er mest tilgængeligt for evt. eksterne programmører.

Du kan bruge scripet som udgangspunkt for din egen integration eller du kan bruge det til inspiration. Scriptet er leveret som det er og DanDomain supporterer ikke dets funktion og tager forbehold for evt. fejl i koden. Det er kun tænkt som et eksempel til at få dig igang.

Scriptet er funktionelt, hvilket vil sige at du kan kopiere det direkte ind i et php dokument, uploade det til et php websted og så kalde det fra en betalingsmetode i DanDomains webshop.

Opsætning

  • Betalingsmetoden skal have Betalings API sat som betalings løsning (Hvilket kræver at appen er aktiv for shoppen)
  • Forretningsnummer feltet bruges ikke til noget i scriptet, da der ikke rent faktisk er et eksternt system at snakke sammen med.
  • API URL skal du udfylde med en absolut URL til et php website hvor du ligger scripet live på nettet.
  • API key er i eksemplet “aaa”.
  • API complete order key er i eksemplet “bbb”.
  • Status feltet bruger scriptet aktivt. Hvis du sætter den til “live” simulerer scriptet en betaling der går godt og hvis du sætter den til “test” simulerer scriptet at betalingen fejler.
  • Tilladte korttyper bruges ikke aktivt til noget af scriptet.

Herunder følger scriptet

//***************************************************************
//This script simulates an integration between the DanDomain shop system and an external payment system.
//The script recieves order data from the shop and an optional checksum is validated by md5.
//The script then completes payment for the order with a serverside callback to the shop (optional callback checksum)
//Finally a return link is generated to for the user to navigate back to the shop complete order step.
//***************************************************************
//Copyright DanDomain A/S 2016, made by DFB
//***************************************************************

//****************
//Global Constants
//****************

$secretKey = "aaa"; //Checksum key
$secretCallbackKey = "bbb"; //Callback cheksum key

//*********************
//Functions list
//*********************
//collectPostVariables
//isChecksummed
//createUnhasedString
//validateHash
//printOrderData
//createCallbacks
//simulateFailedPayment
//simulateFailedPayment
//printAllPOSTVariables
//*********************

//*** collectPostVariables returns POST variables to the script in a global associative array.
//*** Note that these are selected data for demonstration and that many more data is available in the $_POST. These can be viewed with function printAllPOSTVariables.
function collectPostVariables($locals) {
if(empty($_POST)) {
throw new Exception("No POST variables in call.
The script may not have been initiated by a DanDomain shop.
Will not proceed.");
}
else {
$locals['OrdreID'] = $_POST["APIOrderID"];
$locals['APITotalAmount'] = $_POST["APITotalAmount"];
$locals['APIPayGatewayCurrCode'] = $_POST["APIPayGatewayCurrCode"];
$locals['APIkey'] = $_POST["APIkey"];
$locals['APICallBackUrl'] = $_POST["APICallBackUrl"];
$locals['APICallBackOKUrl'] = $_POST["APICallBackOKUrl"];
$locals['APICallBackServerUrl'] = $_POST["APICallBackServerUrl"];
$locals['APIFullCallBackOKUrl'] = $_POST["APIFullCallBackOKUrl"];
$locals['APISessionID'] = $_POST["APISessionID"];
$locals['APITestMode'] = $_POST["APITestMode"];
$locals['APISessionID'] = $_POST["APISessionID"];
echo "Data has been collected from POST variables.
";
}
return $locals;
}

//*** isChecksummed checks to see if a checksum is expected and aborts the scipt if there is no checksum.
//*** The script facilitates both integration with or without checksum, so need to check that state.
function isChecksummed($Key, $APIkey){
if ($Key != Null and $APIkey != Null){
echo "Checksum required and recieved.
Will proceed with validation.
";
return true;
}
elseif ($Key != Null and $APIkey == Null){
throw new Exception("No Checksum recieved, but required by script.
Will not proceed.
");
}
elseif ($Key == Null and $APIkey != Null){
echo "Checksum recieved, but not required by script.
Will proceed.
";
}
else {
echo "No Checksum required by script.
";
}
return false;
}

//*** createUnhasedString prepares a string to be compared to the recieved checksum hash.
//*** This sting is specific for DanDomain systems and is concatinated from OrderID+TotalAmount+SecretKey+currencycode
//*** Eg. " 120+200,00+mySecret+208 " is the string for order 120 where amount is 200 DKK and the key is "mySecret".
//*** NOTE: DanDomain webshop strips thousands seperator in amount before creating checksum, so we have to do the same here.
function createUnhasedString($id, $amount, $key, $currency){
$amount = str_replace(".", "", $amount); //Stripping any '.' in string regardless of localisation
$amount = str_replace(",", "", $amount); //Stripping any ',' in string regardless of localisation
$amount = substr_replace($amount, ',', -2, -2); //Inserting a ',' as decimal seperator for purpose of the checksum validation.
$str = "$id+$amount+$key+$currency";
//echo "Combining unhashed string: ".$str."
"; //Disabled by default. Enable to echo how the sting is combined.
return $str;
}

//*** validateHash validates an MD5 hash with an unhashed string
//*** input the unhased string and the hash that need to be validated.
function validateHash($string, $hash){
$candidate = md5($string);
echo "Hashed candidate: ".$candidate."
";
echo "Recived checksum: ".$hash."
";
if ($candidate != $hash){
throw new Exception("Checksum Error!
Will not proceed.
");
}
else {
echo "Checksum validates.
Will proceed.
";
}
return true;
}

//*** printOrderData prints basic order data on screen
//*** Note that these are selected data for demonstration and that many more data is available in the $_POST. These can be viewed with function printAllPOSTVariables.
function printOrderData($locals){
echo "
Basic order data:
";
echo "Order ID: ".$locals['OrdreID']."
";
echo "Ordrer Total Amount: ".$locals['APITotalAmount']."
";
echo "Currency Code: ".$locals['APIPayGatewayCurrCode']."
";
echo "
";
return true;
}

//*** createCallbacks adds final calback URLs to the global array
//*** First a check is made to see if the callback requires checksum and if so then a checksum string is created.
//*** This sting is specific for DanDomain systems and is concatinated from OrderID+TotalAmount+SecretCallbackKey+Currencycode
//*** Eg. " 120+200,00+myCallbackSecret+208 " is the string for order 120 where amount is 200 DKK and the key is "myCallbackSecret"
//*** Old Method did not include amount in the callback by error, hence the toggle between old and new.
//*** As per version 8.4.10 of the DanDomain shop system, old method is still in effect and therefore default here.
function createCallbacks($locals, $callbackKey, $isOldMethod){

echo "Creating callback URL.
";

$locals['FinalCallbackServerUrl'] = Null;
$locals['FinalFullCallbackOKUrl'] = Null;

if ($callbackKey != Null){
echo "Callback requires checksum.
";
echo "Creating callback checksum.
";

$callbackChecksum = Null;
if ($isOldMethod){
$callbackChecksum = $locals['OrdreID']."+".$callbackKey."+".$locals['APIPayGatewayCurrCode'];
}
else {
$callbackChecksum = $locals['OrdreID']."+".$locals['APITotalAmount']."+".$callbackKey."+".$locals['APIPayGatewayCurrCode'];
}

//echo "Unhashed callback string: ".$callbackChecksum."
"; //Disabled by default. Enable to echo how the sting is combined.
$callbackChecksum = md5($callbackChecksum);
echo "Callback md5 checksum: ".$callbackChecksum."
";
echo "
";
$locals['FinalCallbackServerUrl'] = $locals['APICallBackServerUrl']."&PayApiCompleteOrderChecksum=".$callbackChecksum;
$locals['FinalFullCallbackOKUrl'] = $locals['APIFullCallBackOKUrl']."&PayApiCompleteOrderChecksum=".$callbackChecksum;
}
else {
echo "No callback checksum required.
";
echo "
";
$locals['FinalCallbackServerUrl'] = $locals['APICallBackServerUrl'];
$locals['FinalFullCallbackOKUrl'] = $locals['APIFullCallBackOKUrl'];
}

return $locals;
}

//*** simulateFailedPayment is called to simulate a failed payment.
//*** No serverside call is made, since the payment didn't clear.
//*** Instead a return URL is created for the user to return to /shop/checkout.html
function simulateFailedPayment($locals){
echo "Simulating an unsuccesful payment.
";
echo "
";
echo "The payment has failed.
Click below to return to the shop for other options.
";
echo "User Callback URL:
http://".$locals['APICallBackUrl']."/shop/checkout.html
";
}

//*** simulateSuccesfullPayment is called to simulate a successful payment.
//*** First a serverside callback is made using php CURL feature, to complete the order.
//*** The session ID is returned with the call as a HTTP Header cookie
//*** Then a link is made for the user, for the manuel return to the shop.
function simulateSuccesfullPayment($locals){
echo "Simulating a succesful payment.
";
echo "
";

//The serverside callback
echo "Doing Serverside callback
";

$url = "http://".$locals['FinalCallbackServerUrl']; //This is the final server callback url
echo "The final Server Callback URL:
".$url."
";
echo "
";

//echo "Session:
".$locals['APISessionID']."
"; //Echoing the session ID is disabled by default. Enable if you want to see it
//echo "
";

$headerStr = "Cookie: ".$locals['APISessionID']; //This is the final HTTP header for the callback

//CURL is set up
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($headerStr));

$response = curl_exec($ch); //The actual call is made and the response i saved

curl_close($ch);

//echo $response."
"; //The respose returns an entire webpage, so is disabeled by default. Enable to se it. The script page WILL be ugly.
//echo "
";

//The manual return URL is created
echo "The payment was succesful.
Click below to return to the shop the order confirmation.
";
echo "User Callback URL:
".$locals['FinalFullCallbackOKUrl']."
";
echo "
";
}

//*** printAllPOSTVariables prints all the POST variables recieved by the script on screen for reference.
function printAllPOSTVariables($associativeArray){
if(empty($_POST)) {
echo "No POST variables in call
";
return false;
}
else {
echo "These are all the POST Variables recieved by the script:

";
foreach($associativeArray as $x => $x_value) {
echo "Key=" . $x . ", Value=" . $x_value;
echo "
";
}
}
return true;
}

//**************************
//Main section of the script
//**************************

//Header
echo "
";
echo "******************************************************************************
";
echo "This script simulates an integration between the DanDomain shop system and an external payment system.
";
echo "The script recieves order data from the shop and an optional checksum is validated by md5.
";
echo "The script then completes payment for the order with a serverside callback to the shop (optional callback checksum)
";
echo "Finally a return link is generated to for the user to navigate back to the shop complete order step.
";
echo "******************************************************************************
";
echo "Copyright DanDomain A/S 2016, made by DFB
";
echo "******************************************************************************
";
echo "
";

//Main section is tried for exception handling.
try {
//Setting globals
$globals = Null;
$globals = collectPostVariables($globals, false);

//Handling incomming checksum
if (isChecksummed($secretKey, $globals['APIkey'])){
$str = createUnhasedString($globals['OrdreID'], $globals['APITotalAmount'], $secretKey, $globals['APIPayGatewayCurrCode']);
validateHash($str, $globals['APIkey']);
}

//Printing orderdata
printOrderData($globals);

//Handling callback
if ($globals['APITestMode'] == "True"){
simulateFailedPayment($globals);
}
else {
$globals = createCallbacks($globals, $secretCallbackKey, true); //Note that old medhod is used as default per Marts. 2017. New method may be in effect at a later point.
simulateSuccesfullPayment($globals);
}

// printAllPOSTVariables($_POST); //disabled by default. Enable to see all POST Variables on screen for reference.
}

//Exceptions from main section are caught and the exception error is printed. This terminates the script.
catch(Exception $e) {
echo "Exception Error: ".$e->getMessage();
echo "
";
}

?>

 


Du finder dokumentationen til DanDomain Webshop her: https://webshop-help.dandomain.dk x