1、开发前准备
登录小程序管理后台,设置服务器域名(request请求地址),业务域名,绑定公众号主体,获取公众商户ID,支付密钥,小程序APPID,小程序APP_SECRET
2、预支付接口调取
try{
$order_no = create_order_no('C');
$data = [
'appid'=>Config::get('wechat_config.appid'),
'body'=>'会员充值',
'mch_id'=>'1535585301',
'nonce_str'=>getNonceStr(),
'notify_url'=>'回调地址',
'out_trade_no'=>$order_no,
'openid'=>$this->user['openid'],
'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
'total_fee'=>$this->params['money']*100,
'trade_type'=>'JSAPI'
];
$sign = sign($data);
$data['sign'] = $sign;
$xmldata = xml($data);
$res = CURL(Config::get('wechat_api.wx_pay'),$xmldata);
$result = getxml($res);
if($result['RETURN_CODE'] == "SUCCESS"){
//插入数据库
$info = [
'appId'=>Config::get('wechat_config.appid'),
'timeStamp'=>time(),
'nonceStr'=>getNonceStr(),
'package'=>'prepay_id='.$result['PREPAY_ID'],
'signType'=>'MD5'
];
$info['paySign'] = sign($info);
return [
'status'=>1,
'msg'=>'成功!',
'info'=>$info
];
}else{
return [
'status'=>0,
'msg'=>'操作失败!'
];
}
}catch(Exception $e){
return [
'status'=>0,
'msg'=>'系统错误,请稍后!'
];
}
2、自定义参数
function create_order_no($type = 'D'){
$random = rand(10000,99999);
return $type.date('YmdHis').$random;
}
//随机32位字符串
function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
function sign($data){
$key = '支付密钥';
ksort($data);
$buff = '';
foreach($data as $k=>$v){
if($k!='sign'&&$v!=''&&!is_array($v)){
$buff .= $k.'='.$v.'&';
}
}
$buff = trim($buff,'&');
$string = $buff.'&key='.$key;
$string = md5($string);
$sign = strtoupper($string);
return $sign;
}
function xml($data){
ksort($data);
$data_xml = '<xml>';
foreach($data as $key=>$val){
if(is_numeric($val)){
$data_xml .= '<'.$key.'>'.$val.'</'.$key.'>';
}else{
$data_xml .= '<'.$key.'><![CDATA['.$val.']]></'.$key.'>';
}
}
$data_xml .= '</xml>';
return $data_xml;
}
function getxml($xml){
$p = xml_parser_create();
xml_parse_into_struct($p,$xml,$vals,$index);
xml_parser_free($p);
$data = '';
foreach($index as $key=>$value){
if($key == 'xml' || $key =='XML' ) continue;
$tag = $vals[$value[0]]['tag'];
$value = $vals[$value[0]]['value'];
$data[$tag] = $value;
}
return $data;
}
3、支付回调
$xml = file_get_contents("php://input");
//$data = getxml($xml);
$jsonxml = json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));
$data = json_decode($jsonxml, true);//转成数组,
$data_sign = $data['sign'];
unset($data['sign']);
$sign = sign($data);
if($sign === $data_sign && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ){
//通过金额与订单号去数据库查询是否存在订单
if(!$ret){
echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[订单信息不正确]]></return_msg></xml>';
exit();
}else{
try{
//更新订单及用户余额积分
if($ret1 && $ret2){
Db::commit();
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
exit();
}else{
Db::rollback();
$log_model->save(
[
'title'=>'回调失败1',
'content'=>'回调失败1'
]
);
echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[操作失败]]></return_msg></xml>';
exit();
}
}catch(Exception $e){
echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[操作失败]]></return_msg></xml>';
exit();
}
}
}