PHP game server for TerranQuest. https://terranquest.net

processiap.php 3.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. require 'required.php';
  3. require 'onlyloggedin.php';
  4. function verify_market_in_app($signed_data, $signature, $public_key_base64) {
  5. $key = "-----BEGIN PUBLIC KEY-----\n" .
  6. chunk_split($public_key_base64, 64, "\n") .
  7. '-----END PUBLIC KEY-----';
  8. //using PHP to create an RSA key
  9. $key = openssl_get_publickey($key);
  10. //$signature should be in binary format, but it comes as BASE64.
  11. //So, I'll convert it.
  12. $signature = base64_decode($signature);
  13. //using PHP's native support to verify the signature
  14. $result = openssl_verify(
  15. $signed_data, $signature, $key, OPENSSL_ALGO_SHA1);
  16. if (0 === $result) {
  17. return false;
  18. } else if (1 !== $result) {
  19. return false;
  20. } else {
  21. return true;
  22. }
  23. }
  24. function verify_app_store_in_app($receipt, $is_sandbox) {
  25. //$sandbox should be TRUE if you want to test against itunes sandbox servers
  26. if ($is_sandbox) {
  27. $verify_host = "ssl://sandbox.itunes.apple.com";
  28. } else {
  29. $verify_host = "ssl://buy.itunes.apple.com";
  30. }
  31. $json = '{"receipt-data" : "' . $receipt . '" }';
  32. //opening socket to itunes
  33. $fp = fsockopen($verify_host, 443, $errno, $errstr, 30);
  34. if (!$fp) {
  35. // HTTP ERROR
  36. return false;
  37. } else {
  38. //iTune's request url is /verifyReceipt
  39. $header = "POST /verifyReceipt HTTP/1.0\r\n";
  40. $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
  41. $header .= "Content-Length: " . strlen($json) . "\r\n\r\n";
  42. fputs($fp, $header . $json);
  43. $res = '';
  44. while (!feof($fp)) {
  45. $step_res = fgets($fp, 1024);
  46. $res = $res . $step_res;
  47. }
  48. fclose($fp);
  49. //taking the JSON response
  50. $json_source = substr($res, stripos($res, "\r\n\r\n{") + 4);
  51. //decoding
  52. $app_store_response_map = json_decode($json_source);
  53. $app_store_response_status = $app_store_response_map->{'status'};
  54. if ($app_store_response_status == 0) {//either OK or expired and needs to synch
  55. //here are some fields from the json, btw.
  56. //$json_receipt = $app_store_response_map->{'receipt'};
  57. //$transaction_id = $json_receipt->{'transaction_id'};
  58. //$original_transaction_id = $json_receipt->{'original_transaction_id'};
  59. //$json_latest_receipt = $app_store_response_map->{'latest_receipt_info'};
  60. return true;
  61. } else {
  62. return false;
  63. }
  64. }
  65. }
  66. $purchase_valid = false;
  67. switch ($VARS['os']) {
  68. case 'android':
  69. $purchase_valid = verify_market_in_app($VARS['data'], $VARS['signature'], GOOGLEPLAY_PUBLICKEY);
  70. break;
  71. case 'ios':
  72. $purchase_valid = verify_app_store_in_app($VARS['data'], APP_STORE_SANDBOX);
  73. break;
  74. }
  75. if ($purchase_valid) {
  76. $creditstoadd = $database->select('shopcoins', ['coins'], ['merchid' => $VARS['id']])[0]['coins'];
  77. $database->update('players', ['credits[+]' => $creditstoadd], ['uuid' => $_SESSION['uuid']]);
  78. sendOK();
  79. } else {
  80. sendError(INVALID_IAP, true);
  81. }