<?php
|
include_once '/Common/CommFunc.php';
|
include_once '/Common/Logging.php';
|
include_once '/Common/Signature.php';
|
include_once '/Common/PayOrder.php';
|
include_once "/ProjComm/CfgReader.php";
|
include_once "/db/DBOper.php";
|
|
header("Content-type: text/html; charset=utf-8");
|
// https://open.x7sy.com/sdk_resources/documentDetails?document_id=8
|
// 二、【游戏支付】与【游戏支付回调】流程 -> 回调
|
|
$pre = "pay";
|
// $_SERVER['PHP_SELF'] = /api/x7/$prexxxxx.php
|
// strripos 最后一次出现 / 的位置,再+1得到 $prexxxxx.php
|
// +$pre长度 从$pre后面开始
|
// -4 去除最后的.php
|
$appid = substr($_SERVER['PHP_SELF'], strripos($_SERVER['PHP_SELF'], "/") + 1 + strlen($pre), -4);
|
\Logging\CreateLogging("x7." . $pre . $appid . ".php");
|
|
\Logging\LogInfo("_POST: " . print_r($_POST, true));
|
|
$encryp_data = $_POST['encryp_data'];
|
$extends_info_data = $_POST['extends_info_data'];
|
$game_area = $_POST['game_area'];
|
$game_level = $_POST['game_level'];
|
$game_orderid = $_POST['game_orderid'];
|
$game_role_id = $_POST['game_role_id'];
|
$game_role_name = $_POST['game_role_name'];
|
$sdk_version = $_POST['sdk_version'];
|
$subject = $_POST['subject'];
|
$xiao7_goid = $_POST['xiao7_goid']; // 游戏订单在【小7服务器】中的唯一标识,由于这个是【小7服务器】订单中的唯一标识,建议游戏厂商在游戏方中保存当前字段内容用来标识当前的订单
|
$sign_data = $_POST['sign_data']; // RSA 签名,是将除了当前参数 sign_data 之外的所有参数,根据键名 的正序形式组成的 url。
|
|
if (!$encryp_data || !$game_area || !$game_level || !$game_orderid || !$game_role_id || !$game_role_name || !$subject || !$xiao7_goid || !$sign_data) {
|
Ret("ParamError");
|
exit;
|
}
|
|
if (!\CfgReader\ReadConfig() || !\CfgReader\GetConfigData("x7", "Pubkey_" . $appid, $pubkey)) {
|
Ret("CfgError");
|
exit;
|
}
|
|
// 1)对 sign_data 进行签名验证;
|
// 验签步骤:
|
// 1. 将接收到的sign_data参数进行base64_decode得到【raw_sign_data】
|
// 2. 将除sign_data以外的其他参数按字典序正序排列,再拼接成查询字符串【source_str】,形如:key=value&key=value(无需urlencode)
|
// 3. 将【raw_sign_data】【source_str】与【小7RSA公钥】参数使用签名算法 “SHA1withRSA”(Java,java.security.Signature类)或 “OPENSSL_ALGO_SHA1”(PHP,openssl_verify函数)进行签名verify验证
|
$source_str = "encryp_data=" . $encryp_data . "&extends_info_data=" . $extends_info_data . "&game_area=" . $game_area
|
. "&game_level=" . $game_level . "&game_orderid=" . $game_orderid . "&game_role_id=" . $game_role_id . "&game_role_name=" . $game_role_name
|
. "&sdk_version=" . $sdk_version . "&subject=" . $subject . "&xiao7_goid=" . $xiao7_goid;
|
if (Signature::verify($source_str, $sign_data, $pubkey, OPENSSL_ALGO_SHA1) != 1) {
|
Ret("sign_data_verify_failed");
|
exit;
|
}
|
|
// 2)解密 encryp_data 得到关键数据;这一步解密 encryp_data 将会得到类似这样的字符串 game_orderid= 订单号&guid=游戏用户唯一标识&pay_price=商品金额
|
// 解密步骤:
|
// 1. 将接收到的【encryp_data】进行base64_decode得到【raw_encryp_data】
|
// 2. 使用小7RSA公钥对【raw_encryp_data】进行解密(php: openssl_public_decrypt, java: javax.crypto.Cipher)得到查询字符串(key=value&key=value..)
|
$raw_encryp_data = base64_decode($encryp_data);
|
if (!openssl_public_decrypt($raw_encryp_data, $decrypted_data, Signature::formatRsaPublicKey($pubkey))) {
|
Ret("encryp_data_decrypt_failed", "decrypt false");
|
exit;
|
}
|
// game_orderid String 游戏订单号 2018182571972272
|
// pay_price Float 商品原价(精确到小数点后面两位) 1.00
|
// guid Integer 标识用户在小 7 平台中的唯一标 识 1219663
|
$decryptedKVData = array();
|
$kvlist = explode("&", $decrypted_data);
|
if (isset($kvlist)) {
|
foreach ($kvlist as $value) {
|
$kv = explode("=", $value);
|
if (!$kv || count($kv) != 2) {
|
Ret("encryp_data_decrypt_failed", "kverror:" . $value);
|
exit;
|
}
|
$decryptedKVData[$kv[0]] = $kv[1];
|
}
|
}
|
\Logging\LogInfo("decryptedKVData: " . print_r($decryptedKVData, true));
|
if (
|
!array_key_exists("game_orderid", $decryptedKVData)
|
|| !array_key_exists("pay_price", $decryptedKVData)
|
|| !array_key_exists("guid", $decryptedKVData)
|
) {
|
Ret("encryp_data_decrypt_failed");
|
exit;
|
}
|
|
$orderID = $game_orderid;
|
$serverID = intval($game_area);
|
$pay_time = "";
|
$AccountID = ""; // 此处不传,事先创建订单的db中有
|
$OrderInfo = ""; // 此处不传,事先创建订单的db中有
|
$amount = ""; // 此处不传,事先创建订单的db中有
|
$returnArr = \PayOrder\DoReceivePayOrder($appid, $orderID, $xiao7_goid, $AccountID, $serverID, $OrderInfo, $amount, $pay_time, true, "CheckPayx7bt5");
|
|
$success = "success";
|
$failed = "failed:order error";
|
$result = $failed;
|
$msg = "";
|
|
switch ($returnArr["errorcode"]) {
|
case 1:
|
$result = $success;
|
break;
|
case 2:
|
$result = $success;
|
break;
|
default:
|
if ($returnArr["errordesc"]) {
|
$msg = $returnArr["errordesc"];
|
}
|
break;
|
}
|
Ret($result, $msg);
|
exit;
|
|
/**
|
* x7bt5充值回调额外检查
|
*/
|
function CheckPayx7bt5($dbOrderInfo)
|
{
|
global $xiao7_goid, $game_area, $decryptedKVData;
|
if ($dbOrderInfo["ServerID"] != $game_area) {
|
return "failed:game_area error";
|
}
|
|
if ($dbOrderInfo["OrderID"] != $decryptedKVData["game_orderid"]) {
|
return "failed:game_orderid error";
|
}
|
|
if ($dbOrderInfo["OrderAmount"] != $decryptedKVData["pay_price"]) {
|
return "failed:pay_price error";
|
}
|
|
if ($dbOrderInfo["AccountID"] != $decryptedKVData["guid"]) {
|
return "failed:guid error";
|
}
|
|
if ($dbOrderInfo["State"] == 1) {
|
if ($dbOrderInfo["OrderIDSDK"] != $xiao7_goid) {
|
return "failed:xiao7_goid error";
|
}
|
}
|
return "";
|
}
|
|
function Ret($ret, $msg = "")
|
{
|
global $success;
|
echo $ret;
|
$logMsg = $ret;
|
if ($msg) {
|
$logMsg .= " msg => " . $msg;
|
}
|
if ($ret != $success) {
|
\Logging\LogError($logMsg);
|
} else {
|
\Logging\LogInfo($logMsg);
|
}
|
}
|