微信jsapi 支付可以直接使用 适合微信浏览器使用
//微信jsapi支付 前端
function paySign(){
if (typeof WeixinJSBridge == “undefined”){
$.post(’/mobile/index.php?m=user&a=DakaDoneBywx’,{},res=>{
console.log(res)
if(res.error_code == 10000){
// onBridgeReady(res.info);
}else{
alert(res.msg)
}
},‘json’)
}else{
$.post(’/mobile/index.php?m=user&a=DakaDoneBywx’,{},res=>{
if(res.error_code == 10000){
onBridgeReady(res.info);
}else{
alert(res.msg)
}
},‘json’)
}
}
function onBridgeReady(info){
WeixinJSBridge.invoke(
‘getBrandWCPayRequest’,{
“appId”:info.appId, //公众号名称,由商户传入
“timeStamp”:info.timeStamp, //时间戳,自1970年以来的秒数
“nonceStr”:info.nonceStr, //随机串
“package”:info.package,
“signType”:“MD5”, //微信签名方式:
“paySign”:info.paySign //微信签名
},
function(res){
alert(res.err_msg)
if(res.err_msg == “get_brand_wcpay_request:ok” ){
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
});
}
//微信jsapi 支付 后端
public function actionDakaDoneBywx()
{
// if(input('type') == )
$order['user_id'] = $_SESSION['user_id'];
$order['pay_status'] = 1;
$order['pay_type'] = 'weixin';
$order['pay_out_trade_no'] = date('YmdHis',time()).$_SESSION['user_id'];
$order['pay_money'] = 1;
$order['sign_type'] = 3;
//微信支付参数构造
$param['appid'] = 'XXXXXXXXXXX';
$param['mch_id'] = '1497429492';
$param['nonce_str'] = $this->createNoncestr();
$param['body'] = "三级会员";
$param['out_trade_no'] = $order['pay_out_trade_no'];
$param['total_fee'] = 1;
$param['spbill_create_ip'] = $this->get_client_ip();
$param['notify_url'] = "https://XXXXXXXXXX";
$param['trade_type'] = 'JSAPI';
$param['sign_type'] = 'MD5';
$param['openid'] = M('wechat_user')->where(['ect_uid'=>$_SESSION['user_id']])->find()['openid'];
$param['sign'] = $this->getSign($param);
$xml = $this->arrayToXml($param);
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$data = $this->postXmlCurl($xml,$url);
$info = $this->xmlToArray($data);
if($info['return_code'] == "SUCCESS" && $info['result_code'] == "SUCCESS"){
$return['appId'] = $info['appid'];
$return['timeStamp'] = time();
$return['nonceStr'] = $info['nonce_str'];
$return['package'] = "prepay_id=".$info['prepay_id'];
$return['signType'] = 'MD5';
$pay_sign = $this->getSign($return);
$return['paySign'] = $pay_sign;
exit(json_encode(array('info'=>$return,'error_code'=>10000,'msg'=>'请求成功','ss'=>$info)));
}else{
exit(json_encode(array('error_code'=>10001,'msg'=>'请求失败')));
}
}
protected static function xmlToArray($xml){
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
private static function postXmlCurl($xml, $url, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错,错误码:$error");
}
}
protected function arrayToXml($arr){
$xml = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/*
*排序并格式化参数方法,签名时需要使用
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar = "";
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/*
* 对要发送到微信统一下单接口的数据进行签名
*/
protected function getSign($Obj){
foreach ($Obj as $k => $v){
$param[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($param);
$String = $this->formatBizQueryParaMap($param, false);
//签名步骤二:在string后加入KEY
$String = $String."&key=xxxxxxxxxxxxxxxx";//商户秘钥
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
private function createNoncestr($length = 32)
{
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
private function get_client_ip()
{
if ($_SERVER['REMOTE_ADDR']) {
$cip = $_SERVER['REMOTE_ADDR'];
}
else if (getenv('REMOTE_ADDR')) {
$cip = getenv('REMOTE_ADDR');
}
else if (getenv('HTTP_CLIENT_IP')) {
$cip = getenv('HTTP_CLIENT_IP');
}
else {
$cip = 'unknown';
}
return $cip;
}