Add in-app purchases
parent
cbd3019cad
commit
2da7ba44af
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require 'required.php';
|
||||||
|
require 'onlyloggedin.php';
|
||||||
|
|
||||||
|
if (!$database->has('shopitems', ['merchid' => $VARS['merchid']])) {
|
||||||
|
sendError("That item is not available at this time.", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$shopitem = $database->select('shopitems', ['merchid', 'itemid', 'quantity', 'cost'], ['merchid' => $VARS['merchid']])[0];
|
||||||
|
|
||||||
|
if (!is_empty($VARS['cost']) && !($shopitem['cost'] == $VARS['cost'])) {
|
||||||
|
sendError("That item is no longer available at that price.", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$credits = $database->select('players', ['credits'], ['uuid' => $_SESSION['uuid']])[0]['credits'];
|
||||||
|
if ($credits < $shopitem['cost']) {
|
||||||
|
sendError("You don't have enough money!", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < $shopitem['quantity']; $i++) {
|
||||||
|
$database->insert('inventory', ['playeruuid' => $_SESSION['uuid'], 'itemid' => $shopitem['itemid']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$database->update('players', ['credits' => ($credits - $shopitem['cost'])], ['uuid' => $_SESSION['uuid']]);
|
||||||
|
|
||||||
|
sendOK("Thanks for your purchase!");
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require 'required.php';
|
||||||
|
require 'onlyloggedin.php';
|
||||||
|
|
||||||
|
function verify_market_in_app($signed_data, $signature, $public_key_base64) {
|
||||||
|
$key = "-----BEGIN PUBLIC KEY-----\n" .
|
||||||
|
chunk_split($public_key_base64, 64, "\n") .
|
||||||
|
'-----END PUBLIC KEY-----';
|
||||||
|
//using PHP to create an RSA key
|
||||||
|
$key = openssl_get_publickey($key);
|
||||||
|
//$signature should be in binary format, but it comes as BASE64.
|
||||||
|
//So, I'll convert it.
|
||||||
|
$signature = base64_decode($signature);
|
||||||
|
//using PHP's native support to verify the signature
|
||||||
|
$result = openssl_verify(
|
||||||
|
$signed_data, $signature, $key, OPENSSL_ALGO_SHA1);
|
||||||
|
if (0 === $result) {
|
||||||
|
return false;
|
||||||
|
} else if (1 !== $result) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verify_app_store_in_app($receipt, $is_sandbox) {
|
||||||
|
//$sandbox should be TRUE if you want to test against itunes sandbox servers
|
||||||
|
if ($is_sandbox) {
|
||||||
|
$verify_host = "ssl://sandbox.itunes.apple.com";
|
||||||
|
} else {
|
||||||
|
$verify_host = "ssl://buy.itunes.apple.com";
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = '{"receipt-data" : "' . $receipt . '" }';
|
||||||
|
//opening socket to itunes
|
||||||
|
$fp = fsockopen($verify_host, 443, $errno, $errstr, 30);
|
||||||
|
if (!$fp) {
|
||||||
|
// HTTP ERROR
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
//iTune's request url is /verifyReceipt
|
||||||
|
$header = "POST /verifyReceipt HTTP/1.0\r\n";
|
||||||
|
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||||
|
$header .= "Content-Length: " . strlen($json) . "\r\n\r\n";
|
||||||
|
fputs($fp, $header . $json);
|
||||||
|
$res = '';
|
||||||
|
while (!feof($fp)) {
|
||||||
|
$step_res = fgets($fp, 1024);
|
||||||
|
$res = $res . $step_res;
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
//taking the JSON response
|
||||||
|
$json_source = substr($res, stripos($res, "\r\n\r\n{") + 4);
|
||||||
|
//decoding
|
||||||
|
$app_store_response_map = json_decode($json_source);
|
||||||
|
$app_store_response_status = $app_store_response_map->{'status'};
|
||||||
|
if ($app_store_response_status == 0) {//eithr OK or expired and needs to synch
|
||||||
|
//here are some fields from the json, btw.
|
||||||
|
$json_receipt = $app_store_response_map->{'receipt'};
|
||||||
|
$transaction_id = $json_receipt->{'transaction_id'};
|
||||||
|
$original_transaction_id = $json_receipt->{'original_transaction_id'};
|
||||||
|
$json_latest_receipt = $app_store_response_map->{'latest_receipt_info'};
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$purchase_valid = false;
|
||||||
|
|
||||||
|
switch ($VARS['os']) {
|
||||||
|
case 'android':
|
||||||
|
$purchase_valid = verify_market_in_app($VARS['data'], $VARS['sig'], GOOGLEPLAY_PUBLICKEY);
|
||||||
|
break;
|
||||||
|
case 'ios':
|
||||||
|
$purchase_valid = verify_app_store_in_app($VARS['data'], APP_STORE_SANDBOX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($purchase_valid) {
|
||||||
|
$creditstoadd = $database->select('shopcoins', ['coins'], ['merchid' => $VARS['id']])[0]['coins'];
|
||||||
|
$database->update('players', ['credits[+]' => $creditstoadd], ['uuid' => $_SESSION['uuid']]);
|
||||||
|
sendOK();
|
||||||
|
} else {
|
||||||
|
sendError("Purchase not valid!", true);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require 'required.php';
|
||||||
|
|
||||||
|
$shop = $database->select('shopitems', '*');
|
||||||
|
$coins = $database->select('shopcoins', '*');
|
||||||
|
|
||||||
|
if ($_SESSION['loggedin']) {
|
||||||
|
$balance = $database->select('players', ['credits'], ['uuid' => $_SESSION['uuid']])[0]['credits'];
|
||||||
|
} else {
|
||||||
|
$balance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = [
|
||||||
|
"status" => "OK",
|
||||||
|
"items" => $shop,
|
||||||
|
"coins" => $coins,
|
||||||
|
"balance" => $balance
|
||||||
|
];
|
||||||
|
|
||||||
|
echo json_encode($out);
|
Reference in New Issue