微信h5支付首先商户平台要开通jsapi支付,商户平台要关联公众号,
这里要注意的是h5支付不需要openid,而微信jsapi支付需要openid。jsapi对客户端ip没有要求,而微信h5支付对客户端ip有要求
然后拿到:
$appid = ""; //应用
APPID $mch_id = ""; //微信支付商户号
$key = ""; //微信商户 API 密钥
注意配置相关域名和授权目录
商户平台
公众平台
public function pay()
{
// 获取openid
$pr = req::$forms;
///查询到的价格
$sql="select price,id,no from `sm_order` where no='".$pr['oid']."'";
//echo $sql;die;
$order = db::queryone($sql);
//echo '<pre>';print_r($order);die;
$appAttr = [];
$appAttr['appid'] = $this->appid;
$key = $this->key;
$appAttr['attach'] = '命理学院';
$appAttr['body'] = '星座运势';
$appAttr['detail'] = '{"info":"微信支付"}';
$appAttr['mch_id'] = $this->mch_id;
$appAttr['nonce_str'] = md5(time().rand(1000,9999));
$appAttr['notify_url'] = 'https://你的域名/v1.0.0/XcxPay/FaceAiPay/notify.php';
$appAttr['openid'] = $pr['open_id'];//$_POST['openid'];
$appAttr['out_trade_no'] = $order['no'];//平台内部订单号
$appAttr['spbill_create_ip'] = '127.0.0.1';
$appAttr['total_fee'] = $order['price'] * 100;//单位分
$appAttr['trade_type'] = 'JSAPI';
//推荐上面有数据按官方的“ASCII字典”排序的设键放置数据
$appAttr['sign'] = self::getParam($appAttr,false,$key);
$post_data = "<xml>
<appid>".$appAttr['appid']."</appid>
<attach>".$appAttr['attach']."</attach>
<body>".$appAttr['body']."</body>
<mch_id>".$appAttr['mch_id']."</mch_id>
<detail>".$appAttr['detail']."</detail>
<notify_url>".$appAttr['notify_url']."</notify_url>
<nonce_str>".$appAttr['nonce_str']."</nonce_str>
<openid>".$appAttr['openid']."</openid>
<out_trade_no>".$appAttr['out_trade_no']."</out_trade_no>
<spbill_create_ip>".$appAttr['spbill_create_ip']."</spbill_create_ip>
<total_fee>".$appAttr['total_fee']."</total_fee>
<trade_type>".$appAttr['trade_type']."</trade_type>
<sign>".$appAttr['sign']."</sign>
</xml>";//拼接成 XML 格式
//echo $post_data;die;
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
$dataxml = self::__postXmlCurl($post_data,$url); //后台 POST 微信传参地址 同时取得微信返回的参数
$objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的 XML 转换成数组
//echo '<pre>';print_r($objectxml);die;
$resultData=[];
$resultData['appId']=$appAttr['appid'];
$resultData['nonceStr']=$objectxml['nonce_str'];
$resultData['package']='prepay_id='.$objectxml['prepay_id'];
$resultData['signType']='MD5';
$resultData['timeStamp']=(string)time();
$resultData['paySign']=self::getParam($resultData,false,$key);
echo json_encode($resultData);
die;
}
public function scanquery(){
$pr = req::$forms;
//查询订单状态
$sql="select status from `sm_order` where no='".$pr['oid']."' and product_id='".$pr['star_id']."'";
//echo $sql;die;
$order = db::queryone($sql);
//echo json_decode($order);die;
//echo '<pre>';print_r($order);die;
if($order && $order['status'] == 'PAYED'){
$url = '/xingzuo/?ct=index&ac=xingzuo_info&oid='.$pr['oid'].'&star_id='.$pr['star_id'];
echo '{"status":1,"orderId":"'.$pr['oid'].'","url":"'.$url.'"}';
}else{
echo '{"code":1,"orderId":"'.$pr['oid'].'"}';
}
}
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 __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
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
}else{
$error = curl_errno($ch);
curl_close($ch);
echo "curl 出错,错误码:$error"."<br>";
}
}
private function __get_client_ip() {
if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
$ip = getenv('HTTP_CLIENT_IP');
} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
$ip = getenv('HTTP_X_FORWARDED_FOR');
} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
$ip = getenv('REMOTE_ADDR');
} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
$ip = $_SERVER['REMOTE_ADDR'];
}
return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
}
//对参数排序,生成MD5加密签名
private function getParam($paramArray, $isencode=false,$k)
{
$paramStr = '';
ksort($paramArray);
$i = 0;
foreach ($paramArray as $key => $value)
{
if ($key == 'Signature'){
continue;
}
if ($i == 0){
$paramStr .= '';
}else{
$paramStr .= '&';
}
$paramStr .= $key . '=' . ($isencode?urlencode($value):$value);
++$i;
}
$stringSignTemp=$paramStr."&key=".$k;
$sign=strtoupper(md5($stringSignTemp));
return $sign;
}