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;
-
}