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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
<!--?php <br ?--> //*************************************************************** //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: <a href="http://".$locals['APICallBackUrl']."/shop/checkout.html">http://".$locals['APICallBackUrl']."/shop/checkout.html</a> "; } //*** 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: <a href=".$locals['FinalFullCallbackOKUrl'].">".$locals['FinalFullCallbackOKUrl']."</a> "; 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 " "; } ?> |