Part1 前提条件
使用微信支付必须拥有以下字段, 其中partnerId,partnerKey和paySignKey需要开通微信支付方可获得:
appId - 公众号身份的唯一标识
appSecret - 公众平台接口API密钥
partnerId - 财付通商户身份的标识
partnerKey - 财付通商户权限密钥 Key
paySignKey - 公众号支付请求中用于加密的密钥Key,对应于支付场景中的appKey值
拿到以上字段后在WXConstant.php中进行配置。
Part2 接口封装
微信支付接口文档:使用公众号发起支付请求
1. web页面调用微信支付
调用JS API支付接口getBrandWCPayRequest()能够调出微信支付的页面:
/- / js 调用微信支付页面
- WeixinJSBridge.invoke('getBrandWCPayRequest', {
- appId: appId, // 公众号id
- timeStamp: timeStamp, // 时间戳
- nonceStr: nonceStr, // 随机字符串
- package: package, // 订单详情扩展字符串
- signType: signType, // 签名方式
- paySign: paySign // 签名
- }, function(res) {
- if (res.err_msg != 'get_brand_wcpay_request:ok') {
- alert('支付失败!');
- } else {
- alert('支付成功!');
- }
- });
复制代码
以上代码中,涉及到appId,timeStamp,nonceStr,package,signType和paySign六个参数, 其中主要工作在于生成订单详情扩展字符串package和签名paySign:
1.1 生成订单详情(package)扩展字符串
- $wxpay = WXPay::factory();
- $package = $wxpay->getPackage($orderData);
复制代码
订单详情信息包含有发起支付请求的商户信息和交易信息,重点看其中的3个参数:
out_trade_no - 商户订单号 此订单号由调用者即商户自己生成,在商户内全局唯一来标识该比交易, 微信后台通知商户支付成功时,会将此订单号发送给商户
total_fee - 订单总金额 此次交易的总金额
notify_url - 通知 URL 此url由商户提供,在支付完成后微信将通过此url通知商户订单的支付
1.2 生成支付签名
$paySign = $wxpay->getPaySign();
2. 接收支付结果通知
用户在成功完成支付后,微信后台通知( POST)商户服务器(notify_url)支付结果, 在微信发过来的数据中重点关注以下参数值:
total_fee - 订单总金额
transaction_id - 订单号, 由微信方生成
out_trade_no - 商户订单号,1.1中提到的商户订单号
time_end - 支付完成时间
sign - 签名
接收到微信通知后,在验证签名后,就可以根据out_trade_no对相应的订单进行状态更新了。
- WXPay::factory()->receivePayNotify();
复制代码
3. 发货通知
在收到支付通知后,商户要按时发货,并使用发货通知接口将相关信息同步到微信后台。若微信平台在规定时间内没有收到,将视作发货超时处理。 发货时间限制:虚拟、服务类 24 小时内,实物类 72小时内。
- WXPay::factory()->deliverNotify($postData)
复制代码
4. 查询订单
商户在预期时间内未收到支付结果通知,可以通过此接口查询订单的支付状态
- WXPay::factory()->orderQuery($postData)
复制代码
5. 接收告警通知
微信后台会向商户推送告警 通知,包括发货延迟 、调用失败、通知失败等情况
- WXPay::factory()->receiveAlert($postXML)
复制代码
6. 接收用户维权信息通知
接入微信支付的商户都必须接入用户维权系统,微信将用户投诉内容通过此api发送给商户
- WXPay::factory()->receivePayFeedback($postXML = '')
复制代码
7. 更新用户维权处理结果
商户可以通过此api调用,标记客户的投诉处理状态
- WXPay::factory()->updatePayFeedback(($openId, $feedbackId))
复制代码
- <?php
- /***
- * 微信支付类
- * 接口调试:http://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=pay/index
- *
- * @author zhanghuichao@tencent.com
- *
- */
- class WXPay
- {
- private $appId;
- private $appSecret;
- private $partnerId;
- private $partnerKey;
- private $paySignKey;
-
- private $timeStamp = '';
- private $nonceStr = '';
- private $package = '';
- private $paySign = '';
-
- const SIGN_TYPE = 'SHA1';
- const INPUT_CHARSET = 'UTF-8';
-
- /*
- * 发货通知接口参数
- */
- protected $deliverNotifyParams = array(
- 'appid' => array(
- 'isRequired' => 1,
- 'defaultValue' => WXConstant::APP_ID,
- 'desc' => '公众平台账户的 AppId'
- ),
- 'openid' => array(
- 'isRequired' => 1,
- 'desc' => '购买用户的 OpenId'
- ),
- 'transid' => array(
- 'isRequired' => 1,
- 'desc' => '交易单号'
- ),
- 'out_trade_no' => array(
- 'isRequired' => 1,
- 'desc' => '第三方订单号'
- ),
- 'deliver_timestamp' => array(
- 'isRequired' => 1,
- 'desc' => '发货时间戳,这里指的是 Linux 时间戳'
- ),
- 'deliver_status' => array(
- 'isRequired' => 1,
- 'desc' => '发货状态,1 表明成功,0 表明失败,失败时需要在 deliver_msg 填上失败原因;'
- ),
- 'deliver_msg' => array(
- 'isRequired' => 1,
- 'desc' => '发货状态信息'
- ),
- 'sign_method' => array(
- 'isRequired' => 1,
- 'defaultValue' => 'sha1',
- 'desc' => '发货状态信息'
- ),
- );
-
- /*
- * 支付回调通知接口参数
- */
- protected $notifyParams = array(
- 'sign_type' => array(
- 'isRequired' => 0,
- 'name' => '签名方式',
- 'desc' => '签名类型,取值:MD5、RSA,默 认:MD5; String(8)'
- ),
- 'input_charset' => array(
- 'isRequired' => 0,
- 'name' => '签名方式',
- 'desc' => '字符编码,取值:GBK、UTF-8,默 认:GBK。; String(8)'
- ),
- 'sign' => array(
- 'isRequired' => 1,
- 'name' => '签名',
- 'desc' => '签名; String(32)'
- ),
- 'trade_mode' => array(
- 'isRequired' => 1,
- 'name' => '交易模式',
- 'desc' => '1-即时到账 其他保留; Int'
- ),
- 'trade_state' => array(
- 'isRequired' => 1,
- 'name' => '交易状态',
- 'desc' => '支付结果: 0—成功 其他保留;Int'
- ),
- 'partner' => array(
- 'isRequired' => 1,
- 'name' => '商户号',
- 'desc' => '商户号,也即之前步骤的 partnerid, 由微信统一分配的 10 位正整数 (120XXXXXXX)号; String(10)'
- ),
- 'bank_type' => array(
- 'isRequired' => 1,
- 'name' => '付款银行',
- 'desc' => '银行类型,在微信中使用 WX ; String(16)'
- ),
- 'bank_billno' => array(
- 'isRequired' => 0,
- 'name' => '银行订单号',
- 'desc' => '银行订单号; String(32)'
- ),
- 'total_fee' => array(
- 'isRequired' => 1,
- 'name' => '总金额',
- 'desc' => '支付金额,单位为分,如果 discount 有值,通知的 total_fee + discount = 请求的 total_fee; Int'
- ),
- 'fee_type' => array(
- 'isRequired' => 1,
- 'name' => '币种',
- 'desc' => '现金支付币种 ,目前只支持人民币 , 默认值是 1-人民币; Int'
- ),
- 'notify_id' => array(
- 'isRequired' => 1,
- 'name' => '通知ID',
- 'desc' => '支付结果通知 id,对于某些特定商 户,只返回通知 id,要求商户据此 查询交易结果; String(128)'
- ),
- 'transaction_id' => array(
- 'isRequired' => 1,
- 'name' => '订单号',
- 'desc' => '交易号,28 位长的数值,其中前 10 位为商户号,之后 8 位为订单产生 的日期,如 20090415,最后 10 位 是流水号。; String(28)'
- ),
- 'out_trade_no' => array(
- 'isRequired' => 1,
- 'name' => '商户订单号',
- 'desc' => '商户系统的订单号,与请求一致; String(32)'
- ),
- 'attach' => array(
- 'isRequired' => 0,
- 'name' => '商户数据包',
- 'desc' => '商户数据包,原样返回,空参数不传递; String(127)'
- ),
- 'time_end' => array(
- 'isRequired' => 1,
- 'name' => '支付完成时间',
- 'desc' => '支付完成时间,格式 为 yyyyMMddhhmmss,如 2009 年 12 月27日9点10分10秒表示 为 20091227091010 。时区为 GMT+8 beijing。; String(14)'
- ),
- 'transport_fee' => array(
- 'isRequired' => 0,
- 'name' => '物流费用',
- 'desc' => '物流费用,单位分,默认 0。如果 有值,必须保证 transport_fee + product_fee = total_fee; Int'
- ),
- 'product_fee' => array(
- 'isRequired' => 0,
- 'name' => '物品费用',
- 'desc' => '物品费用,单位分。如果有值,必 证保须 transport_fee +product_fee=total_fee; Int'
- ),
- 'discount' => array(
- 'isRequired' => 0,
- 'name' => '物品费用',
- 'desc' => '折扣价格,单位分,如果有值,通 知的 total_fee + discount = 请求 的 total_fee; Int'
- ),
- );
-
- /*
- * 订单详情package参数
- */
- protected $packageParams = array(
- 'bank_type' => array(
- 'isRequired' => 1,
- 'defaultValue' => 'WX',
- 'name' => '银行通道类型',
- 'desc' => '字符串类型, 为定固"WX" ,注意 大写'
- ),
- 'body' => array(
- 'isRequired' => 1,
- 'name' => '商品描述',
- 'desc' => '字符串类型, 128 字节以下'
- ),
- 'attach' => array(
- 'isRequired' => 0,
- 'name' => '附加数据',
- 'desc' => '附加数据,原样返回;字符串类型, 128 字节以下'
- ),
- 'partner' => array(
- 'isRequired' => 1,
- 'defaultValue' => WXConstant::PARTNER_ID,
- 'name' => '商户号',
- 'desc' => '注册时分配的财付通商户号 partnerId;字符串类型'
- ),
- 'out_trade_no' => array(
- 'isRequired' => 1,
- 'name' => '商户订单号',
- 'desc' => '商户系统内部的订单号,32 个字符内、可包含字 母;确保在商户系统唯一;字符串类型, 32字节以下'
- ),
- 'total_fee' => array(
- 'isRequired' => 1,
- 'name' => '订单总金额',
- 'desc' => '字符串类型'
- ),
- 'fee_type' => array(
- 'isRequired' => 1,
- 'defaultValue' => 1,
- 'name' => '支付币种',
- 'desc' => '字符串类型,默认值是1;暂只支持1'
- ),
- 'notify_url' => array(
- 'isRequired' => 1,
- 'defaultValue' => WXConstant::PAY_NOTIFY_URL,
- 'name' => '通知URL',
- 'desc' => '字符串类型,在支付完成后,接收微信通知支付结果的 URL, 需给绝对路径, 255字符内'
- ),
- 'spbill_create_ip' => array(
- 'isRequired' => 1,
- 'name' => '订单生成的机器IP',
- 'desc' => '字符串类型,指用户浏览器端 IP,不是商户服务器 IP,格式为 IPV4; 15字符内'
- ),
- 'time_start' => array(
- 'isRequired' => 0,
- 'name' => '交易起始时间',
- 'desc' => '字符串类型,订单生成时间,格式为 yyyyMMddHHmmss,如 2009年12月25日9点10分10秒表示 为 20091225091010,时区为 GMT+8 beijing;该时间取自商户服务器; 14字符内'
- ),
- 'time_expire' => array(
- 'isRequired' => 0,
- 'name' => '交易结束时间',
- 'desc' => '字符串类型,订单生成时间,格式为 yyyyMMddHHmmss,如 2009年12月25日9点10分10秒表示 为 20091225091010,时区为 GMT+8 beijing;该时间取自商户服务器; 14字符内'
- ),
- 'transport_fee' => array(
- 'isRequired' => 0,
- 'name' => '物流费用',
- 'desc' => '字符串类型,物流费用,单位为分。如果有值,必须保 证 transport_fee + product_fee=total_fee;'
- ),
- 'product_fee' => array(
- 'isRequired' => 0,
- 'name' => '商品费用',
- 'desc' => '字符串类型,物流费用,单位为分。如果有值,必须保 证 transport_fee + product_fee=total_fee;'
- ),
- 'goods_tag' => array(
- 'isRequired' => 0,
- 'name' => '商品标记',
- 'desc' => '字符串类型,商品标记,优惠券时可能用到'
- ),
- 'input_charset' => array(
- 'isRequired' => 1,
- 'defaultValue' => self::INPUT_CHARSET,
- 'name' => '传入参数字符 编码',
- 'desc' => '字符串类型,取值范围:GBK、UTF-8,默认:GBK'
- ),
- );
-
- public static function factory()
- {
- return new self();
- }
-
- public function __construct()
- {
- // @todo validate these values
- $this->appId = WXConstant::APP_ID;
- $this->appSecret = WXConstant::APP_SECRET;
- $this->partnerId = WXConstant::PARTNER_ID;
- $this->partnerKey = WXConstant::PARTNER_KEY;
- $this->paySignKey = WXConstant::PAY_SIGN_KEY;
- }
-
- /**
- * 获取jsapi支付请求json
- * @return string
- */
- public function getBrandWCPayRequestParam($orderData)
- {
- $this->timeStamp = $this->getTimeStamp();
- $this->nonceStr = $this->getNoncestr();
- $this->package = $this->getPackage($orderData);
- $this->paySign = $this->getPaySign();
- $params = array(
- 'appId' => $this->appId,
- 'timeStamp' => (string)$this->timeStamp,
- 'nonceStr' => $this->nonceStr,
- 'package' => $this->package,
- 'signType' => self::SIGN_TYPE,
- 'paySign' => $this->paySign,
- 'outTradeNo' => $orderData['out_trade_no'],
- );
-
- return $params;
- }
-
- /**
- * 获取支付签名
- */
- public function getPaySign($data = '')
- {
- // @todo 如果$data为空,则要检查$this->nonceStr, $this->package, $this->timeStamp是否为空
- $params = array(
- 'appid' => $this->appId,
- 'appkey' => $this->paySignKey,
- 'noncestr' => isset($data['noncestr']) ? $data['noncestr'] : $this->nonceStr,
- 'package' => isset($data['package']) ? $data['package'] : $this->package,
- 'timestamp' => isset($data['timestamp']) ? $data['timestamp'] : $this->timeStamp,
- );
-
- return $this->createPaySign($params);
- }
-
- /**
- * 支付签名算法
- * @param unknown $params
- * @return string
- */
- public function createPaySign($params)
- {
- ksort($params);
- $string1 = $this->httpBuildStr($params);
- $paySign = sha1($string1);
-
- return $paySign;
- }
-
- /**
- * 获取订单详情(package)扩展字符串
- * @return string
- */
- public function getPackage($orderData)
- {
- // 构造参数数组
- $myPackageParams = array();
- foreach ($this->packageParams as $key => $val) {
- if ($val['isRequired']) {
- $myPackageParams[$key] = isset($orderData[$key]) ? $orderData[$key] : (isset($val['defaultValue']) ? $val['defaultValue'] : '');
- if (!$myPackageParams[$key]) {
- throw new WXPayException("Please specify value for $key", -5000);
- }
- } else {
- if (isset($orderData[$key]) && $orderData[$key]) {
- $myPackageParams[$key] = $orderData[$key];
- }
- }
- }
-
- // 构造sign
- $sign = $this->createPackageSign(&$myPackageParams);
-
- // 构造urlencoded params string
- $paramsStringEncoded = http_build_query($myPackageParams);
-
- // 拼接
- $return = $paramsStringEncoded . '&sign=' . $sign;
-
- return $return;
- }
-
- /**
- * 创建订单详情package签名
- * @param unknown $packageParams
- * @return string
- */
- public function createPackageSign($packageParams)
- {
- ksort($packageParams);
- $paramsString = $this->httpBuildStr($packageParams);
- $sign = strtoupper(md5($paramsString . '&key=' . WXConstant::PARTNER_KEY));
-
- return $sign;
- }
-
- /**
- * 拼接query字符串
- * 相当于没有urlencode功能的http_build_query()
- * @param unknown $params
- * @return string
- */
- private function httpBuildStr($params)
- {
- $return = '';
- foreach ($params as $key => $val) {
- $return[] = implode('=', array($key, $val));
- }
- $return = implode('&', $return);
-
- return $return;
- }
-
- private function getTimeStamp()
- {
- return time();
- }
-
- /**
- * 获取随机字符串
- * 商户生成的随机字符串;取值范 围:长度为 32 个字符以下。由商户生成后传入。取值范围:32 字符以下
- * @return string
- */
- private function getNoncestr($length = 16)
- {
- $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- $str ="";
- for ( $i = 0; $i < $length; $i++ ) {
- $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
- }
-
- return $str;
- }
-
- /**
- * 接收微信的支付回调通知
- *
- data from wx notify:
- array (
- '$_GET' => array (
- 'bank_billno' => '201409028971856',
- 'bank_type' => '3006',
- 'discount' => '0',
- 'fee_type' => '1',
- 'input_charset' => 'UTF-8',
- 'notify_id' => 'qZ6Aae9b0UKIxhbQrM8tRZ1EVUJzAu14yvcTu_URSbzAnBkJD-nu218tG8sISJCSccacsSPOey1NQhopDUdzhNqb-s0Zpe2i',
- 'out_trade_no' => 'audia354058517b30b1',
- 'partner' => '1220730901',
- 'product_fee' => '1',
- 'sign' => 'AD7342AEB7B043E7E3DEF2BF3CCFF7CD',
- 'sign_type' => 'MD5',
- 'time_end' => '20140902165147',
- 'total_fee' => '1',
- 'trade_mode' => '1',
- 'trade_state' => '0',
- 'transaction_id' => '1220730901201409023179351860',
- 'transport_fee' => '0',
- ),
- 'postData' => ' 1 1409647907 ',
- )
- */
- public function receivePayNotify($notifyData = '')
- {
- // 读取数据
- if (!$notifyData) {
- $postData = file_get_contents('php://input');
- $notifyData = array(
- '$_GET' => $_GET,
- 'postData' => $postData,
- );
- }
-
- // 日志
- WXBasic::factory()->doLog($notifyData, __METHOD__, 'mp.weixin.qq.com');
-
- // 校验签名
- $notifySign = $notifyData['$_GET']['sign'];
- unset($notifyData['$_GET']['sign']);
- $mySign = $this->createPackageSign($notifyData['$_GET']);
- if ($notifySign != $mySign) {
- throw new WXPayException('notify sign validate failed:' . '$notifySign=' . $notifySign . ';$mySign='. $mySign, WXPayException::NOTIFY_SIGN_VALIDATE_FAILED);
- }
-
- // 验证接收到的订单信息
- $notifyOutTradeNo = $notifyData['$_GET']['out_trade_no'];
- $notifyTradeState = $notifyData['$_GET']['trade_state'];
- $notifyTotalFee = $notifyData['$_GET']['total_fee'];
- if ($notifyTradeState != 0) {
- // @todo 告警
- }
-
- // 比对订单数据$myPackage
- $myPackage = Order::factory()->selectByOutTradeNo($notifyOutTradeNo);
- if (!$myPackage) {
- throw new WXPayException('notify out_trade_no not exist: ' . '$notifyOutTradeNo=' . $notifyOutTradeNo, WXPayException::NOTIFY_OUT_TRADE_NO_NOT_EXIST);
- }
- if ($notifyTotalFee != $myPackage['FTotalFee']) {
- throw new WXPayException("notify total_fee incorrect:notifyTotalFee=$notifyTotalFee,myTotalFee={$myPackage['FTotalFee']}", WXPayException::NOTIFY_TOTAL_FEE_INCORRECT);
- }
-
-
- // 更新本地订单信息
- $notifyData = array(
- 'FTimeEnd' => isset($notifyData['$_GET']['time_end']) ? $notifyData['$_GET']['time_end'] : '',
- 'FTradeState' => isset($notifyData['$_GET']['trade_state']) ? $notifyData['$_GET']['trade_state'] : '',
- 'FBankBillNo' => isset($notifyData['$_GET']['bank_billno']) ? $notifyData['$_GET']['bank_billno'] : '',
- 'FBankType' => isset($notifyData['$_GET']['bank_type']) ? $notifyData['$_GET']['bank_type'] : '',
- 'FTransactionId' => isset($notifyData['$_GET']['transaction_id']) ? $notifyData['$_GET']['transaction_id'] : '',
- 'FNotifyId' => isset($notifyData['$_GET']['notify_id']) ? $notifyData['$_GET']['notify_id'] : '',
- 'FTimePayNotify' => date('Y-m-d H:i:s'),
- );
- Order::factory()->updateByOutTradeNo($notifyOutTradeNo, $notifyData);
-
-
- // 应答
- return 'success';
- }
-
- /**
- * 发货通知 delivernotify
- * 通知微信已发货
- *
- * 第三方在收到最终支付通知之后,调用发货通知 API 告知微信后台该订单的发货状态。
- * 发货时间限制:虚拟、服务类 24 小时内,实物类 72 小时内
- * 若微信平台在规定时间内没有收到,将视作发货超时处理。
- *
- * 微信返回数据:
- * {"errcode":0,"errmsg":"ok"}
- * {"errcode":49004,"errmsg":"not match signature"}
- * {"errcode":49001,"errmsg":"not same appid with appid of access_token"}
- */
- public function deliverNotify(array $postData)
- {
- // 检查参数
- $myPostData = array();
- foreach ($this->deliverNotifyParams as $key => $val) {
- if ($val['isRequired']) {
- $myPostData[$key] = isset($postData[$key]) ? $postData[$key] : (isset($val['defaultValue']) ? $val['defaultValue'] : '');
- if (!$myPostData[$key]) {
- throw new WXPayException("Please specify value for $key", WXPayException::API_PARAM_ERROR);
- }
- } else {
- if (isset($postData[$key]) && $postData[$key]) {
- $myPostData[$key] = $postData[$key];
- }
- }
- }
- // 构造url
- $accessToken = WXBasic::factory()->getAccessToken();
- $url = WXConstant::PAY_DELIVER_NOTIFY_URL . "?access_token=$accessToken";
-
- // 根据支付签名( paySign)生成方法中所讲的签名方式生成,
- $signMethod = $myPostData['sign_method'];
- unset($myPostData['sign_method']); // sign_method 是签名方法(不计入签名生成)
- $myPostData['appkey'] = isset($myPostData['appkey']) ? $myPostData['appkey'] : $this->paySignKey;
- $myPostData['app_signature'] = $this->createPaySign($myPostData);
- $myPostData['sign_method'] = $signMethod;
- unset($myPostData['appkey']); // appkey参加签名字段,但不需要传递
- $myPostData = json_encode($myPostData);
-
- // 验证通知结果
- $res = WXBasic::factory()->sendPostRequest($url, $myPostData);
- if ($res['errcode'] != 0) {
- throw new WXPayException($res['errmsg'], WXPayException::DELIVER_NOTIFY_ERROR);
- }
-
- return $res;
- }
-
- /**
- * 查询订单orderquery
- * 向微信查询订单信息
- *
- * @param array $postData
- * array(
- * 'out_trade_no' => ?,
- * )
- *
- * 微信返回数据:
- {"errcode":49001,"errmsg":"not same appid with appid of access_token"}
- {"errcode":49004,"errmsg":"not match signature"}
- {"errcode":0,"errmsg":"ok","order_info":{
- "ret_code":0,
- "ret_msg":"",
- "input_charset":"GBK",
- "trade_state":"0",
- "trade_mode":"1",
- "partner":"1220730901",
- "bank_type":"CMB_FP",
- "bank_billno":"201409028971856",
- "total_fee":"1",
- "fee_type":"1",
- "transaction_id":"1220730901201409023179351860",
- "out_trade_no":"audia354058517b30b1",
- "is_split":"false",
- "is_refund":"false",
- "attach":"",
- "time_end":"20140902165147",
- "transport_fee":"0",
- "product_fee":"1",
- "discount":"0",
- "rmb_total_fee":""}
- }
- */
- public function orderQuery(array $postData)
- {
- // 构造参数
- $myPostData['appid'] = isset($postData['appid']) ? $postData['appid'] : $this->appId;
- $myPostData['package'] = isset($postData['$package']) ? $postData['$package'] : '';
- $myPostData['timestamp'] = isset($postData['timestamp']) ? $postData['timestamp'] : time();
- $myPostData['app_signature'] = isset($postData['app_signature']) ? $postData['app_signature'] : '';
- $myPostData['sign_method'] = isset($postData['sign_method']) ? $postData['sign_method'] : 'sha1';
- if (!$myPostData['package']) {
- $outTradeNo = isset($postData['out_trade_no']) ? $postData['out_trade_no'] : '';
- $partner = isset($postData['partner']) ? $postData['partner'] : $this->partnerId;
- $sign = isset($postData['sign']) ? $postData['sign'] : '';
- if (!$outTradeNo) {
- throw new WXPayException('please specify out_trade_no', WXPayException::API_PARAM_ERROR);
- }
- // 生成签名
- if (!$sign) {
- $partnerKey = $this->partnerKey;
- $sign = strtoupper(md5("out_trade_no=$outTradeNo&partner=$partner&key=$partnerKey"));
- }
- $myPostData['package'] = "out_trade_no=$outTradeNo&partner=$partner&sign=$sign";
- }
- // 生成签名
- if (!$myPostData['app_signature']) {
- $myPostData['app_signature'] = $this->createPaySign(array(
- 'appid' => $myPostData['appid'],
- 'appkey' => $this->paySignKey,
- 'package' => $myPostData['package'],
- 'timestamp' => $myPostData['timestamp'],
- ));
- }
-
- $url = WXConstant::PAY_ORDER_QUERY_URL . "?access_token=" . WXBasic::factory()->getAccessToken();
- $res = WXBasic::factory()->sendPostRequest($url, json_encode($myPostData));
- if ($res['errcode'] != 0) {
- throw new WXPayException($res['errmsg'], WXPayException::ORDER_QUERY_ERROR);
- }
-
- return $res;
- }
-
- /**
- * 接收来自微信的用户维权信息通知
- * @param string $postXML
- * @throws WXPayException
- */
- public function receivePayFeedback($postXML = '')
- {
- if (!$postXML) {
- $postXML = file_get_contents('php://input');
- }
-
- // 日志
- WXBasic::factory()->doLog($postXML, __METHOD__, 'mp.weixin.qq.com');
-
- $postData = WXBasic::factory()->xml2Array($postXML);
-
- // 校验AppSignature
- $myAppSignature = $this->createPaySign(array(
- 'appid' => $postData['appid'],
- 'appkey' => $this->paySignKey,
- 'timestamp' => $postData['timestamp'],
- 'openid' => $postData['openid'],
- ));
- if ($myAppSignature != $postData['AppSignature']) {
- throw new WXPayException('pay feedback sign validate failed:' . 'AppSignature=' . $postData['AppSignature'] . ';$myAppSignature='. $myAppSignature, WXPayException::PAY_FEEDBACK_SIGN_VALIDATE_FAILED);
- }
-
- switch ($postData['MsgType']) {
- // 用户提交投诉
- case 'request':
- break;
- // 用户确认消除投诉
- case 'confirm':
- break;
- // 用户拒绝消除投诉
- case 'reject':
- break;
- default:
- break;
- }
-
- // @todo 投诉单入库/更新投诉单状态
-
- // 应答
- return 'ok';
- }
-
- /**
- * 标记客户的投诉处理状态
- *
- * 微信返回数据:
- * {"errcode":0,"errmsg":"ok"}
- * @param unknown $openId
- * @param unknown $feedbackId
- * @throws WXPayException
- */
- public function updatePayFeedback($openId, $feedbackId)
- {
- $url = WXConstant::PAY_FEEDBACK_UPDATE_URL . "?access_token=" . WXBasic::factory()->getAccessToken()
- . "&openid=$openId"
- . "&feedbackid=$feedbackId";
- $res = WXBasic::factory()->sendGETRequest($url);
- if ($res['errcode'] != 0) {
- throw new WXPayException($res['errmsg'], WXPayException::PAY_FEEDBACK_UPDATE_ERROR);
- }
-
- return $res;
- }
-
- /**
- * 接收告警信息
- * @throws WXPayException
- * @return string
- */
- public function receiveAlert($postXML)
- {
- if (!$postXML) {
- $postXML = file_get_contents('php://input');
- }
-
- // 日志
- WXBasic::factory()->doLog($postXML, __METHOD__, 'mp.weixin.qq.com');
-
- $postData = WXBasic::factory()->xml2Array($postXML);
-
- // 校验AppSignature
- $myAppSignature = $this->createPaySign(array(
- 'alarmcontent' => $postData['alarmcontent'],
- 'appid' => $postData['appid'],
- 'appkey' => $this->paySignKey,
- 'description' => $postData['description'],
- 'errortype' => $postData['errortype'],
- 'timestamp' => $postData['timestamp'],
- ));
- if ($myAppSignature != $postData['AppSignature']) {
- throw new WXPayException('pay feedback sign validate failed:' . 'AppSignature=' . $postData['AppSignature'] . ';$myAppSignature='. $myAppSignature, WXPayException::PAY_ALERT_SIGN_VALIDATE_FAILED);
- }
-
- // @todo 告警通知入库
-
- return 'success';
- }
-
- /**
- * 接收前端js的支付回调结果
- * 注意这里没有签名机制,非100%可信
- */
- public function recieveJsCallback($openId, $outTradeNo)
- {
- return Order::factory()->update(array('FTimeJSCallback' => date('Y-m-d H:i:s')), array('FOutTradeNo' => $outTradeNo, 'FOpenId' => $openId));
- }
-
- }
复制代码
|