service = new CallbackService(); parent::__construct($name); } public function index() { return 1; } //获取微信回调http头信息 private function getHeaders() { $headers = []; foreach ($_SERVER as $key => $value) { if ('HTTP_' == substr($key, 0, 5)) { $headers[str_replace('_', '-', substr($key, 5))] = $value; } if (isset($_SERVER['PHP_AUTH_DIGEST'])) { $header['AUTHORIZATION'] = $_SERVER['PHP_AUTH_DIGEST']; } elseif (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $header['AUTHORIZATION'] = base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW']); } if (isset($_SERVER['CONTENT_LENGTH'])) { $header['CONTENT-LENGTH'] = $_SERVER['CONTENT_LENGTH']; } if (isset($_SERVER['CONTENT_TYPE'])) { $header['CONTENT-TYPE'] = $_SERVER['CONTENT_TYPE']; } } return $headers; } /** * @throws \Exception */ public function wxpay() { //读取http头信息 见下文 $header = $this->getHeaders(); // 请根据实际情况获取 $inWechatpaySignature = isset($header['WECHATPAY-SIGNATURE']) ? $header['WECHATPAY-SIGNATURE'] : ""; // 请根据实际情况获取 $inWechatpayTimestamp = isset($header['WECHATPAY-TIMESTAMP']) ? $header['WECHATPAY-TIMESTAMP'] : ""; // 请根据实际情况获取 // $inWechatpaySerial = $header['WECHATPAY-SERIAL']; // 请根据实际情况获取 $inWechatpayNonce = isset($header['WECHATPAY-NONCE']) ? $header['WECHATPAY-NONCE'] : ""; //读取微信传过来的信息,是一个json字符串 $inBody = file_get_contents('php://input'); $config = WxService::wxPayConfigByType("app"); // 在商户平台上设置的APIv3密钥 $apiv3Key = $config["mch_v3_api"]; // 根据通知的平台证书序列号,查询本地平台证书文件 $platformPublicKeyInstance = Rsa::from("file://" . $config["platform_certificate_file_path"], Rsa::KEY_TYPE_PUBLIC); // 检查通知时间偏移量,允许5分钟之内的偏移 $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp); // 构造验签名串 $verifiedStatus = Rsa::verify( Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), $inWechatpaySignature, $platformPublicKeyInstance ); if ($timeOffsetStatus && $verifiedStatus) { // 转换通知的JSON文本消息为PHP Array数组 $inBodyArray = (array)json_decode($inBody, true); // 使用PHP7的数据解构语法,从Array中解构并赋值变量 ['resource' => [ 'ciphertext' => $ciphertext, 'nonce' => $nonce, 'associated_data' => $aad ]] = $inBodyArray; // 加密文本消息解密 $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad); // 把解密后的文本转换为PHP Array数组 $inBodyResourceArray = (array)json_decode($inBodyResource, true); if (isset($inBodyResourceArray["out_trade_no"]) && isset($inBodyResourceArray["trade_state"])) { if ($inBodyResourceArray["trade_state"] == "SUCCESS") { if (false !== stristr($inBodyResourceArray["out_trade_no"], "RBU")) { $res = $this->service->rechargeBalanceSuccess($inBodyResourceArray["out_trade_no"]); } else if (false !== stristr($inBodyResourceArray["out_trade_no"], "RBM")) { $res = $this->service->rechargeMembershipSuccess($inBodyResourceArray["out_trade_no"]); } else { $res = $this->service->payOrderSuccess($inBodyResourceArray["out_trade_no"]); } $response_code = 200; $response_body = ["code" => "SUCCESS", "message" => "成功"]; if (0 == $res->code()) { $response_code = 500; $response_body = ["code" => "FAIL", "message" => "失败"]; } \think\Log::custom_log("微信支付回调 no:{$inBodyResourceArray["out_trade_no"]}!", [ "inBodyResourceArray" => $inBodyResourceArray, "res" => [$res->code(), $res->msg(), $res->data()], "response_code" => $response_code, "response_body" => $response_body ]); return new Response(json_encode($response_body), $response_code); } } } \think\Log::custom_log("微信支付回调, 支付失败! inBody", $inBody); return new Response(json_encode(["code" => "FAIL", "message" => "失败"]), 500); } public function wxrefund() { //读取http头信息 见下文 $header = $this->getHeaders(); // 请根据实际情况获取 $inWechatpaySignature = isset($header['WECHATPAY-SIGNATURE']) ? $header['WECHATPAY-SIGNATURE'] : ""; // 请根据实际情况获取 $inWechatpayTimestamp = isset($header['WECHATPAY-TIMESTAMP']) ? $header['WECHATPAY-TIMESTAMP'] : ""; // 请根据实际情况获取 // $inWechatpaySerial = $header['WECHATPAY-SERIAL']; // 请根据实际情况获取 $inWechatpayNonce = isset($header['WECHATPAY-NONCE']) ? $header['WECHATPAY-NONCE'] : ""; //读取微信传过来的信息,是一个json字符串 $inBody = file_get_contents('php://input'); $config = WxService::wxPayConfigByType("app"); // 在商户平台上设置的APIv3密钥 $apiv3Key = $config["mch_v3_api"]; // 根据通知的平台证书序列号,查询本地平台证书文件 $platformPublicKeyInstance = Rsa::from("file://" . $config["platform_certificate_file_path"], Rsa::KEY_TYPE_PUBLIC); // 检查通知时间偏移量,允许5分钟之内的偏移 $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp); // 构造验签名串 $verifiedStatus = Rsa::verify( Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), $inWechatpaySignature, $platformPublicKeyInstance ); if ($timeOffsetStatus && $verifiedStatus) { // 转换通知的JSON文本消息为PHP Array数组 $inBodyArray = (array)json_decode($inBody, true); // 使用PHP7的数据解构语法,从Array中解构并赋值变量 ['resource' => [ 'ciphertext' => $ciphertext, 'nonce' => $nonce, 'associated_data' => $aad ]] = $inBodyArray; // 加密文本消息解密 $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad); // 把解密后的文本转换为PHP Array数组 $inBodyResourceArray = (array)json_decode($inBodyResource, true); if (isset($inBodyResourceArray["out_trade_no"]) && isset($inBodyResourceArray["refund_status"])) { if ($inBodyResourceArray["refund_status"] == "SUCCESS") { $res = $this->service->refundSuccess($inBodyResourceArray["out_trade_no"]); $response_code = 200; $response_body = ["code" => "SUCCESS", "message" => "成功"]; if (0 == $res->code()) { $response_code = 500; $response_body = ["code" => "FAIL", "message" => "失败"]; } \think\Log::custom_log("微信退款回调 no:{$inBodyResourceArray["out_trade_no"]}!", [ "inBodyResourceArray" => $inBodyResourceArray, "res" => [$res->code(), $res->msg(), $res->data()], "response_code" => $response_code, "response_body" => $response_body ]); return new Response(json_encode($response_body), $response_code); } } } \think\Log::custom_log("微信支付退款回调, 支付失败! inBody", $inBody); return new Response(json_encode(["code" => "FAIL", "message" => "失败"]), 500); } public function alipay() { echo "SUCCESS"; } }