jiqing9006

wx.requestPayment 发起微信支付

timeStamp 时间戳

nonceStr 随机字符串

package 统一下单接口返回的 prepay_id 参数值

signType 签名算法

paySign 支付签名

success 接口成功回调

fail 接口失败回调

complete 接口完成回调(成功,失败都执行)

1.先调用后台接口,生产基本数据

// 获取店铺信息
Api.BalancePay({
    openid: openid,
    amount: amount,
    bid: bid,
}).then(res => {
    if (res.errno) {
        wx.showToast({ title: res.errdesc });
        return;
    }
    var data = res.data;
    ...
})

具体的这个是做什么的呢?

判断用户是否存在。

判断充值id是否存在。

判断充值金额是否合法。

创建充值订单。

创建统一支付订单。

public function unifiedorder($openid,$order_num,$total_fee,$products_name){
        $trade_no = $order_num;
        $url = \'https://api.mch.weixin.qq.com/pay/unifiedorder\';
        $data = [
            \'appid\'             => C(\'APPID\'),
            \'mch_id\'            => C(\'MCHID\'),
            \'nonce_str\'         => $this->createNonceStr(),
            \'sign_type\'         => \'MD5\',
            \'body\'              =>  $products_name,  //商品名称组合
            \'attach\'            => C(\'PAY_ATTACH_NAME\'),
            \'out_trade_no\'      => $trade_no,        //订单号
            \'fee_type\'          => \'CNY\',
            \'total_fee\'         => $total_fee,
            \'spbill_create_ip\'  => $_SERVER[\'REMOTE_ADDR\'],
            \'goods_tag\'         => C(\'PAY_ATTACH_NAME\'),
            \'notify_url\'        => \'https://a.squmo.com/\'.C(\'PAY_URL_NAME\').\'/Recharge/order_notice\',
            \'trade_type\'        => \'JSAPI\',
            \'openid\'            => $openid
        ];

        // 获取签名
       $sign = $this->MakeSign($data);
       $data[\'sign\'] = $sign;
       $xml = $this->ToXml($data);
       vendor(\'Func.Http\');
       // 提交获取数据
       $result = $this->FromXml(Http::postXmlCurl($url,$xml));
       return $result;
}

一切准备就绪之后,将一些数据返回给小程序。

$unifiedorder = $this->unifiedorder($openid,$order_num,$total_price,$products_name);
$data = [
    \'appId\'     => C(\'APPID\'),
    \'timeStamp\' => time(),
    \'nonceStr\'  => $this->createNonceStr(),
    \'package\'   => \'prepay_id=\'.$unifiedorder[\'prepay_id\'],
    \'signType\'  => \'MD5\'
];
// 获取签名
$sign = $this->MakeSign($data);
$data[\'sign\'] = $sign;
$this->json->setAttr(\'data\',$data);
$this->json->Send();

2.再发起微信支付

wx.requestPayment({
        \'timeStamp\': data.timeStamp.toString(),
        \'nonceStr\': data.nonceStr,
        \'package\': data.package,
        \'signType\': \'MD5\',
        \'paySign\': data.sign,
        \'success\': function (res) {
            console.log(\'支付成功\');
        },
        \'fail\': function (res) {
            console.log(\'支付失败\');
            return;
        },
        \'complete\': function (res) {
            console.log(\'支付完成\');
            var url = that.data.url;
            console.log(\'get url\', url)
            if (res.errMsg == \'requestPayment:ok\') {
                wx.showModal({
                    title: \'提示\',
                    content: \'充值成功\'
                });
                if (url) {
                    setTimeout(function () {
                        wx.redirectTo({
                            url: \'/pages\' + url
                        });
                    }, 2000)
                } else {
                    setTimeout(() => {
                        wx.navigateBack()
                    }, 2000)
                }
            }
            return;
        }
});

3.支付成功的回调(异步操作)

//微信支付回调
public function order_notice(){
    // 微信公众平台推送过来的post数据
    $xml = $GLOBALS[\'HTTP_RAW_POST_DATA\'];
    // 获取数据
    $data = $this->FromXml($xml);
    // 保存微信服务器返回的签名sign
    $data_sign = $data[\'sign\'];
    // sign不参与签名算法
    unset($data[\'sign\']);

    $sign = $this->makeSign($data);
    // 判断签名是否正确  判断支付状态
    if ( ($sign===$data_sign) && ($data[\'return_code\']==\'SUCCESS\') && ($data[\'result_code\']==\'SUCCESS\') ) {
        $result = $data;
        //获取服务器返回的数据
        $order_num = $data[\'out_trade_no\'];         //订单单号
        $openid = $data[\'openid\'];                  //付款人openID
        $total_fee = $data[\'total_fee\'];            //付款金额
        $transaction_id = $data[\'transaction_id\'];  //微信支付流水号
        $user = M(\'user\');
        $user_flag = $user->where(array(\'openid\'=>$openid))->find();
        $save_data = array(
            \'total_payed_price\' =>  $total_fee,     //实际到帐金额
            \'transaction_id\'    =>  $transaction_id,
            \'paytime\'           =>  time(),
            \'status\'            =>  2       //1未支付;2已支付;3已申请退款;4已退款;5已完成
        );
        $recharge = M(\'recharge\');
        $recharge_flag=$recharge->where(array(\'recoder\'=>$order_num,\'uid\'=>$user_flag[\'id\']))->find();
        $recharge_amount=$recharge_flag[\'amount\'];
        $recharge_save_flag =$recharge->where(array(\'recoder\'=>$order_num,\'uid\'=>$user_flag[\'id\']))->save($save_data);
        if($recharge_save_flag){
            $save_balance[\'balance\']= $user_flag[\'balance\']+$recharge_amount;
            $result_balance =$user->where(array(\'openid\'=>$openid))->save($save_balance);
        }
    }else{
        $result = false;
    }
    // 返回状态给微信服务器
    if ($result) {
        $str=\'<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>\';
    }else{
        $str=\'<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>\';
    }
    echo $str;
    return $result;
}

其他常用函数

	public function FromXml($xml)
    {
        if(!$xml){
            throw new WxPayException("xml数据异常!");
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, \'SimpleXMLElement\', LIBXML_NOCDATA)), true);
        return $this->values;
    }

    public function ToXml($array){
        if(!is_array($array)|| count($array) <= 0){
           return ;
        }
        $xml = \'<xml version="1.0">\';
        foreach ($array as $key=>$val){
            if (is_numeric($val)){
              $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    private function MakeSign($data)
    {
        //签名步骤一:按字典序排序参数
        ksort($data);
        $string = $this->ToUrlParams($data);
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=".C(\'WEIXIN_PAY_KEY\');
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    private function ToUrlParams($array)
    {
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

分类:

技术点:

相关文章: