//to do 微信支付
$user = $this->auth->getUser();
$openid = $this->auth->getUser()->openid; //当前用户openid
$appid = 'wx********'; //小程序appid
$mch_id = '15********'; //商户id
$key = '*****'; //商户号秘钥
$nonce_str = 'omso8gakbdqtxmzjc63pcj0b71v5qy68'; //随机32(不能高于32)位字符串
$body = '商品的标题'; //商品的标题
$out_trade_no = $order_num; //订单号
$total_fee = $price*100; //金额
$spbill_create_ip = get_client_ip();//获取用户服务器IP
$notify_url = 'https:********';//回调地址
$trade_type = 'JSAPI';//签名类型
$data = compact('body', 'appid','mch_id', 'nonce_str','out_trade_no','total_fee','spbill_create_ip', 'notify_url','trade_type','openid');//王八的屁股,规定
$sign = get_sign($data, $key, false);//生成签名
$info =[
'appid' =>$appid,
'mch_id'=>$mch_id,
'nonce_str'=>$nonce_str,
'sign'=>$sign,
'body'=>$body,
'out_trade_no'=>$out_trade_no,
'total_fee'=>$total_fee,
'spbill_create_ip'=>$spbill_create_ip,
'notify_url'=>$notify_url,
'trade_type'=>$trade_type,
'openid'=>$user['openid']
];
// 将数组转化成XML格式 arrayToXml
$info = $this->arrayToXml($info);
// print_r($info);exit;
$data = $this->curl_post('https://api.mch.weixin.qq.com/pay/unifiedorder',$info);
// var_dump($data);exit;
// XML转成数组
$data1 = $this->xmlToArray($data);
// var_dump($data1);exit;
$prepay_id = $data1['prepay_id'];
$time = time();
$params_for_paysign = compact('appid','nonce_str','prepay_id','time');
// var_dump($params_for_paysign);exit;
$paySign = strtoupper(MD5("appId=$appid&nonceStr=$nonce_str&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$time&key=$key"));
// var_dump($paySign);exit;
file_put_contents('2.txt',$prepay_id.PHP_EOL.$paySign);
// $paysign = get_sign($params_for_paysign, $key, false);
return json(['code'=>1,'msg'=>'','data'=>['appId'=>$appid,'nonceStr'=>$nonce_str,'package'=>'prepay_id='.$prepay_id,'signType'=>'MD5','timeStamp'=>$time,'paySign'=>$paySign]]);
回调代码
/**
* 回调
*/
public function back()
{
$xml = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
if (empty($xml)) {
# 如果没有数据,直接返回失败
return "错误";
}
// return $xml;
$info1 = $this->xmlToArray($xml);
$appid = $info1['appid'];
$mch_id = $info1['mch_id'];
$nonce_str = $info1['nonce_str'];
$transaction_id = $info1['transaction_id'];
$sign = strtoupper(md5("appid=$appid&mch_id=$mch_id&nonce_str=$nonce_str&transaction_id=$transaction_id&key=*********"));
$info2 = [
'appid'=>$info1['appid'],
'mch_id'=>$info1['mch_id'],
'nonce_str'=>$info1['nonce_str'],
'transaction_id'=>$info1['transaction_id'],
'sign'=>$sign,
];
$info3 = $this->arrayToXml($info2);
$xml_data = $this->curl_post('https://api.mch.weixin.qq.com/pay/orderquery',$info3);
$end_data = $this->xmlToArray($xml_data);
if ($end_data['return_msg']!="OK"){
$this->error('签名错误');
}
Db::startTrans();
try {
//成功
//成功后的逻辑
Db::commit();
} catch (\Exception $e) {
// file_put_contents('4.txt',$end_data['out_trade_no']);
Db::rollback();
}
}
common.php 中用到的方法
<?php
// 微信特殊字符转化
function filterEmoji($str)
{
$str = preg_replace_callback(
'/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? '' : $match[0];
},
$str);
return $str;
}
//解密
function decryptData( $appid, $sessionKey, $encryptedData, $iv, &$data )
{
$OK = 0;
$IllegalAesKey = -41001;
$IllegalIv = -41002;
$IllegalBuffer = -41003;
$DecodeBase64Error = -41004;
if (strlen($sessionKey) != 24) {
return $IllegalAesKey;
}
$aesKey=base64_decode($sessionKey);
if (strlen($iv) != 24) {
return $IllegalIv;
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
//var_dump($aesKey,$aesIV,$aesCipher);
$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj=json_decode( $result );
if( $dataObj == NULL )
{
return $IllegalBuffer;
}
if( $dataObj->watermark->appid != $appid )
{
return $IllegalBuffer;
}
$data = $result;
return $OK;
}
/**
* 生成签名
* @param WxPayConfigInterface $config 配置对象
* @param String $key 商户秘钥
* @param bool $needSignType 是否需要补signtype
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
function get_sign($config, $key, $needSignType = true)
{ $sign_type = 'MD5';
if($needSignType) {
$sign_type = GetSignType();
}
//签名步骤一:按字典序排序参数
ksort($config);
$string = ToUrlParams($config);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$key;
//签名步骤三:MD5加密或者HMAC-SHA256
if($sign_type == "MD5"){
$string = md5($string);
} else if($sign_type == "HMAC-SHA256") {
$string = hash_hmac("sha256", $string, $key);
} else {
throw new Exception("签名类型不支持!");
}
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 获取客户端IP地址
* @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
* @param boolean $adv 是否进行高级模式获取(有可能被伪装)
* @return mixed
*/
function get_client_ip($type = 0,$adv=false) {
$type = $type ? 1 : 0;
static $ip = NULL;
if ($ip !== NULL) return $ip[$type];
if($adv){
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos = array_search('unknown',$arr);
if(false !== $pos) unset($arr[$pos]);
$ip = trim($arr[0]);
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
// IP地址合法验证
$long = sprintf("%u",ip2long($ip));
$ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
return $ip[$type];
}
/**
* 格式化参数格式化成url参数
* @param $config array 待排序的参数数组
*/
function ToUrlParams($config)
{
$buff = "";
foreach ($config as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
*
* 产生随机字符串,不长于32位
* @param int $length
* @return 产生的随机字符串
*/
function get_nonce_str($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
//订单号
function build_order_no()
{
return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//数组转xml
function arrayToXml($arr) {
$xml = "<xml>";
foreach ($arr as $key => $val){
$xml.="<$key>$val</$key>";
}
if (!is_numeric($val)){
$xml.="<$key>$val</$key>";
}
else
$xml.="<$key><![CDATA[$val]]></$key>";
// }
$xml.="</xml>";
return $xml;
}
//Xml转数组
function xmlToArray($xml) {
$arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $arr;
}
/**
* 发送post请求
*/
public function curl_post($url , $data=array()){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
// POST数据
curl_setopt($ch, CURLOPT_POST, 1);
// 把post的变量加上
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
common中的方法不一定都能用上,缺啥拿啥,然后就成功了