|
- <?php
-
- namespace Kuxin\Weixin;
-
- use Kuxin\Config;
- use Kuxin\Helper\Http;
- use Kuxin\Helper\Json;
- use Kuxin\Helper\Xml;
- use Kuxin\Request;
-
- class Pay extends Weixin
- {
- const API_UNIFIED_ORDER = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
- const API_ORDER_QUERY = 'https://api.mch.weixin.qq.com/pay/orderquery';
-
- const TRADE_TYPE_JSAPI = 'JSAPI';
- const TRADE_TYPE_NATIVE = 'NATIVE';
- const TRADE_TYPE_MWEB = 'MWEB';
-
- public function unifiedorder($data, $tradeType = self::TRADE_TYPE_JSAPI)
- {
- $data = array_merge([
- 'appid' => $this->appId,
- 'mch_id' => Config::get('weixin.mchid'),
- 'nonce_str' => $this->getNonceStr(),
- 'notify_url' => Config::get('weixin.notifyurl'),
- 'spbill_create_ip' => $tradeType == self::TRADE_TYPE_NATIVE ? Config::get('server_ip', gethostbyname($_SERVER['SERVER_NAME'])) : Request::getIp(),
- 'trade_type' => $tradeType,
- ], $data);
- $data['sign'] = $this->makeSign($data);
- $xml = Xml::encode($data);
- $res = Http::post(self::API_UNIFIED_ORDER, $xml);
- if ($res) {
- $res = Xml::decode($res);
- if ($res['return_code'] != 'SUCCESS') {
- return $res['return_msg'];
- }
- if (isset($res['result_code']) && $res['result_code'] == 'FAIL') {
- return $res['err_code'] . ':' . $res['err_code_des'];
- }
- return $res;
- } else {
- return '统一下单请求失败';
- }
- }
-
- public function notify($data = null)
- {
- if (!$data) {
- $data = file_get_contents('php://input');
- }
- $data = Xml::decode($data);
- if (isset($data['return_code']) && $data['return_code'] == 'SUCCESS') {
- if ($data['sign'] == $this->makeSign($data)) {
- return [
- 'id' => $data['out_trade_no'],
- 'is_subscribe' => $data['is_subscribe'],
- 'openid' => $data['openid'],
- 'attach' => isset($data['attach']) ? $data['attach'] : "",
- 'time_end' => strtotime($data['time_end']),
- 'transaction_id' => $data['transaction_id'],
- 'money' => $data['total_fee'] / 100,
- ];
- } else {
- return '签名验证失败';
- }
- } else {
- return '解析数据失败';
- }
- }
-
- public function query($orderId)
- {
- $data = [
- 'appid' => $this->appId,
- 'mch_id' => Config::get('weixin.mchid'),
- 'out_trade_no' => $orderId,
- 'nonce_str' => $this->getNonceStr(),
- ];
- $data['sign'] = $this->makeSign($data);
- $xml = Xml::encode($data);
- if ($res = Http::post(self::API_ORDER_QUERY, $xml)) {
- $res = Xml::decode($res);
- if ($res['return_code'] != 'SUCCESS') {
- return $res['return_msg'];
- }
- if (isset($res['result_code']) && $res['result_code'] == 'FAIL') {
- return $res['err_code'] . ':' . $res['err_code_des'];
- }
- return $res;
- } else {
- return '订单查询请求失败';
- }
-
- }
-
- public function jsPayConfig($prepay_id, $json = true)
- {
- $data = [
- 'appId' => $this->appId,
- 'timeStamp' => (string)$_SERVER['REQUEST_TIME'],
- 'nonceStr' => $this->getNonceStr(),
- 'package' => 'prepay_id=' . $prepay_id,
- 'signType' => 'MD5',
- ];
- $data['paySign'] = $this->makeSign($data);
- return $json ? Json::encode($data) : $data;
- }
-
- /**
- * 格式化参数格式化成url参数
- */
- public function toUrlParams($data)
- {
- $buff = "";
- foreach ($data as $k => $v) {
- if ($k != "sign" && $v != "" && !is_array($v)) {
- $buff .= $k . "=" . $v . "&";
- }
- }
-
- $buff = trim($buff, "&");
- return $buff;
- }
-
- /**
- * 生成签名
- *
- * @return string 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
- */
- public function makeSign($data)
- {
- //签名步骤一:按字典序排序参数
- ksort($data);
- $string = $this->toUrlParams($data);
- //签名步骤二:在string后加入KEY
- $string = $string . "&key=" . Config::get('weixin.paykey');
- //签名步骤三:MD5加密
- $string = md5($string);
- //签名步骤四:所有字符转为大写
- $result = strtoupper($string);
- return $result;
- }
-
- }
|