123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?php
- /**
- * 接收华为后台通知(支付)
- * @version
- * 1.0.0 Created at 2018-3-1. by --gwang
- * @author gwang (mail@wanggangzero.cn)
- * @copyright ? 2018-3-1, SJZ LoyalSoft Corporation & gwang. All rights reserved.
- *
- */
- include_once __DIR__ . '/../../../main.php'; # 导入game utils
- include_once __DIR__ . '/../Mo/resp.php'; # 导入通用返回值结构
- include_once __DIR__ . '/../Mo/payRequest.php'; # 导入通用返回值结构
- require_once __DIR__ . '/../Mo/OrderNotice.php';
- require_once 'config.huawei.php'; # 配置文件
- // 签名算法
- use loyalsoft\CLog;
- use loyalsoft\HttpUtil;
- use loyalsoft\pay\OrderNotice;
- header("Content-Type: application/json; charset=utf-8");
- /**
- * 华为验签算法
- * @param type $params
- * @return boolean
- */
- function verify_sign_huawei($params)
- {
- ksort($params);
- $sign = $params['sign'];
- $signType = isset($params['signType']) ? $params['signType'] : "RSA"; # 默认RSA
- $form = $params;
- unset($form['sign']);
- unset($form['signType']);
- if (empty($sign)) {
- return false;
- }
- $content = "";
- $i = 0;
- foreach ($form as $key => $value) {
- if ($key != "sign" && $key != "signType") {
- $content .= ($i == 0 ? '' : '&') . $key . '=' . $value;
- }
- $i++;
- }
- $pubKey = config_for_huawei::Inst()->getPubkey();
- $openssl_public_key = @openssl_get_publickey($pubKey);
- if (!$openssl_public_key) {
- return false;
- }
- $ok = @openssl_verify($content, base64_decode($sign), $openssl_public_key, $signType);
- @openssl_free_key($openssl_public_key);
- return $ok;
- }
- class OrderNotice_huawei extends OrderNotice
- {
- static public function Parse($args)
- {
- $o = new OrderNotice();
- $o->callbackInfo = rawurldecode($args['extReserved']); # 透传参数, uid-uc,zoneid,cpOrderId
- $extArgs = explode(',', $o->callbackInfo);
- $o->channel = "huawei"; # 渠道代码
- $o->cpOrderId = $args['requestId']; # 订单编号
- $o->status = ($args["result"] == "0") ? 1 : 2; # 订单状态(华为返回值: 0/成功, 1. 退款成功(暂未启用), 其他失败)
- $o->uid = $extArgs[0]; // openid # 玩家uid
- $o->amount = $args['amount'] * 100; # 支付金额, 统一单位是分
- $o->sdk_orderid = $args['orderId']; # 华为支付平台订单编号
- // $o->otherInfo = $args['notifyTime'];
- return $o;
- }
- }
- try {
- HttpUtil::PostOnly(); # 华为那边肯定以POST方式来发送消息
- CLog::pay("[notify.华为] 收到支付回调请求: " . HttpUtil::getQueryString());
- $cfg = config_for_huawei::Inst(); # 配置信息
- $params = HttpUtil::getQueryParas(); # 提取参数
- if ($sign != verify_sign_huawei($params)) { # 验证签名
- exit('{"result":1}'); # 返回验签失败
- }
- $order = OrderNotice_huawei::Parse($params); # 将参数归一化到order
- if ($order != null) {
- if ($order->Check()) { # 订单校验, 1代表支付成功
- if ($order->status == 1) { # 订单状态是成功
- $order->UpdateOrderStatus(); # 更新订单状态,->已付款
- CLog::pay("[notify.华为] [发货] 订单: " . $order->cpOrderId . ", 金额: " . $order->amount);
- } else if ($order->status == 2) { # status为2(failed)的情况
- $order->UpdateOrderStatus(); # 直接更新订单状态,->支付失败
- CLog::pay("[notify.华为] [不发货] 订单: " . $order->cpOrderId);
- } else {
- echo 'FAILURE';
- CLog::pay("[notify.华为][处理结果]: FAILURE (未知的支付状态)"); # 日志
- return;
- }
- echo 'SUCCESS'; //返回给sdk server的响应内容
- CLog::pay("[notify.华为][处理结果]:" . "SUCCESS"); # 日志
- return;
- }
- }
- CLog::pay("[notify.华为][处理结果]:" . "FAILURE"); # 日志
- echo 'FAILURE'; //返回给sdk server的响应内容 ,对于重复多次通知失败的订单,请参考文档中通知机制。
- return;
- } catch (Exception $e) {
- CLog::pay("[notify.华为]" . $e->getMessage()); # 日志
- throw new exception($e->getMessage());
- }
|