首页/新闻资讯/正文
微信小程序支付功能实现指南:接入流程与关键设置步骤

 2025年09月05日  阅读 2

摘要:1.接入微信支付及商户信息设置要实现微信小程序的支付功能,首先需要在微信小程序管理后台进行支付配置。进入微信小程序管理后台,找到「微信支付」选项,点击「接入微信支付」。如果是首次接入,选择「我还没有商户号」选项,按照指引完成商户号的申请流程。完成商户号申...

1. 接入微信支付及商户信息设置

要实现微信小程序的支付功能,首先需要在微信小程序管理后台进行支付配置。进入微信小程序管理后台,找到「微信支付」选项,点击「接入微信支付」。如果是首次接入,选择「我还没有商户号」选项,按照指引完成商户号的申请流程。

完成商户号申请后,需要配置两个关键信息:

1. 设置支付授权目录

在商户平台(pay.weixin.qq.com)中,进入「产品中心」→「开发配置」,添加支付授权目录。该目录需要与小程序后端支付接口的路径保持一致,确保支付请求的合法性。例如,如果你的支付接口路径是 https://yourdomain.com/api/pay,则授权目录应填写 https://yourdomain.com/api/

2. 设置API密钥

在商户平台的「账号中心」→「API安全」→「设置密钥」中,生成并保存API密钥。该密钥用于后续签名校验,务必妥善保管,避免泄露。

2. 开发小程序支付页面

在小程序前端,需要创建一个支付页面,通常包含金额输入框和支付按钮。以下是一个简单的页面结构示例:


<view>
  <input placeholder="请输入金额" bindinput="inputAmount" />
  <button bindtap="handlePay">立即支付</button>
</view>

在对应的JS文件中,处理用户输入并调用支付接口:


Page({
  data: { amount: '' },
  inputAmount: function(e) { this.setData({ amount: e.detail.value }); },
  handlePay: function() {
    if (!this.data.amount) return wx.showToast({ title: '请输入金额', icon: 'none' });
    wx.request({
      url: 'https://yourdomain.com/api/pay',
      method: 'POST',
      data: { amount: this.data.amount },
      success: function(res) {
        wx.requestPayment({
          timeStamp: res.data.timeStamp,
          nonceStr: res.data.nonceStr,
          package: res.data.package,
          signType: 'MD5',
          paySign: res.data.paySign,
          success: () => wx.showToast({ title: '支付成功' }),
          fail: () => wx.showToast({ title: '支付失败', icon: 'none' })
        });
      }
    });
  }
});

3. 服务器端支付逻辑实现(PHP示例)

服务器端负责生成支付参数并签名。以下是一个PHP示例:


<?php
function generatePayParams($appid, $mch_id, $api_key, $openid, $amount) {
  $nonceStr = md5(uniqid());
  $timeStamp = time();
  $outTradeNo = $mch_id . time(); // 商户订单号
  
  // 统一下单API请求
  $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  $params = [
    'appid' => $appid,
    'mch_id' => $mch_id,
    'nonce_str' => $nonceStr,
    'body' => '小程序支付',
    'out_trade_no' => $outTradeNo,
    'total_fee' => $amount * 100, // 单位为分
    'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
    'notify_url' => 'https://yourdomain.com/api/notify',
    'trade_type' => 'JSAPI',
    'openid' => $openid
  ];
  
  // 生成签名
  ksort($params);
  $stringA = '';
  foreach ($params as $k => $v) $stringA .= $k . '=' . $v . '&';
  $stringSignTemp = $stringA . 'key=' . $api_key;
  $sign = strtoupper(md5($stringSignTemp));
  $params['sign'] = $sign;
  
  // 请求微信接口
  $xml = '<xml>';
  foreach ($params as $k => $v) $xml .= "<$k>$v</$k>";
  $response = curl_post($url, $xml);
  $result = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA);
  
  // 返回小程序支付参数
  return [
    'timeStamp' => "$timeStamp",
    'nonceStr' => $nonceStr,
    'package' => 'prepay_id=' . $result->prepay_id,
    'signType' => 'MD5',
    'paySign' => md5("appId=$appid&nonceStr=$nonceStr&package=prepay_id=$result->prepay_id&signType=MD5&timeStamp=$timeStamp&key=$api_key")
  ];
}
?>

4. 支付回调处理与验证

支付完成后,微信服务器会异步通知支付结果。需要在服务器端编写回调接口验证签名并处理业务逻辑:


<?php
function notifyCallback() {
  $xml = file_get_contents('php://input');
  $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  
  // 验证签名
  $sign = $data['sign'];
  unset($data['sign']);
  ksort($data);
  $stringA = '';
  foreach ($data as $k => $v) $stringA .= $k . '=' . $v . '&';
  $stringSignTemp = $stringA . 'key=' . $api_key;
  if ($sign !== strtoupper(md5($stringSignTemp))) exit('fail');
  
  // 处理业务逻辑(如更新订单状态)
  if ($data['return_code'] === 'SUCCESS') {
    // 更新数据库订单状态为已支付
    file_put_contents('notify.log', date('Y-m-d H:i:s') . json_encode($data) . "\n", FILE_APPEND);
  }
  echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}
?>

5. 注意事项与常见问题

1. 金额单位:微信支付以分为单位,前端传入的金额需乘以100。

formSubmit:function(e){
    let pp = e.detail.value;
  
    if(pp.money.trim()=="")
    {
      wx.showToast({
        title: "请输入捐赠金额!", //显示文本
        icon: 'none', //使用图标
        duration: 1000  //显示时间
      })
      return false;
    }
    // 注意,下面的reqest代码部分,that.data.userInfo.wid存储的就是当前用户的openid,这个信息一般会在用户登录后进行了存储,如果你没有存储,可以通过wx.login去获取,此处不再赘述
    let that = this; 
    wx. request({
      url:'刚刚在上面设置的安全支付目录地址/'+that.data.userInfo.wid+'/'+pp.money,
      header: {
        'content-type': 'application/json' // 默认值
      }, 
      success: function (ress){ 
        // success
        let res = ress.data;  
        if (res.status){
          let out_trade_no = res.out_trade_no;//记录商户订单号 ,为后续缴费成功回调做记录
          wx.requestOrderPayment ({ 
            'timeStamp': res.timeStamp,
            'nonceStr': res.nonceStr,
            'package': res.package, 
            'signType': 'MD5',
            'paySign': res.paySign,  
            'success': function(res3){ 
              wx.showToast({
                title: "支付成功,感谢您的善心!", 
                icon: 'success', //使用图标
                duration: 1000  //显示时间
              })
              //此处负责回调,把先前的订单状态值为已付款
            },
            'fail':function (res2){
              console.log (res2);
            }
          })  
        }  
      },
      fail: function () {
        //后台没连上
      } ,
      complete: function () {
      // 处理结束
      } 
    })
  },

2. 域名配置:确保服务器域名已在小程序后台的「开发管理」→「开发设置」中配置。

3. 证书问题:如果使用退款功能,需在商户平台下载API证书。

4. 测试建议:正式上线前使用微信支付的沙箱环境测试(金额需≤1元)。

5. 安全提醒:API密钥和商户号属于敏感信息,不要明文存储在前端代码中。

通过以上步骤,即可完成微信小程序支付功能的完整接入。建议在实际开发中加入异常处理和日志记录,便于排查问题。

//支付调用的主函数, 名称需要和设置的商户支付授权目录一致
public function payOP(){
		 
		//获取opid和fee
		$wid= $this->uri->segment(3,0);	//获取小程序传过来的openid
	    $fee = $this->uri->segment(4,0);//获取小程序传过来的捐款
	 
	    //设置参数
	    $appid =        'xxxxx';//小程序的appid ,如果是公众号 就是公众号的appid
	    $body =         '本次支付的介绍,文字信息随便写';
	    $mch_id =       '商户平台登录账号';
	    $nonce_str =    $this->nonce_str();//随机字符串,下面会提供函数
	    $notify_url =   '微信支付回调函数,说实话这个没啥用,不设应该不行,你就设置成你的reqest域名吧';
	    $openid =       $wid;//当前支付用户的openid
	    $out_trade_no = date('YmdHis_', time()).ceil(microtime()*1000);//商户订单号,需唯一
	    $spbill_create_ip = '114.114.114.114';//随便一个真实存在的ip,必须要设置
	    $total_fee =    $fee*100;//因为充值金额最小是1 而且单位为分 如果是充值1元所以这里需要*100
	    $trade_type = 'JSAPI';//交易类型 默认
	 
	    //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
	    $post['appid'] = $appid;
	    $post['body'] = $body;
	    $post['mch_id'] = $mch_id;
	    $post['nonce_str'] = $nonce_str;//随机字符串
	    $post['notify_url'] = $notify_url;
	    $post['openid'] = $openid;
	    $post['out_trade_no'] = $out_trade_no;
	    $post['spbill_create_ip'] = $spbill_create_ip;//终端的ip
	    $post['total_fee'] = $total_fee;//总金额 最低为一块钱 必须是整数
	    $post['trade_type'] = $trade_type;
	    $sign = $this->sign($post);//签名
   
	    $post_xml = '
	           '.$appid.'
	           '.$body.'
	           '.$mch_id.'
	           '.$nonce_str.'
	           '.$notify_url.'
	           '.$openid.'
	           '.$out_trade_no.'
	           '.$spbill_create_ip.'
	           '.$total_fee.'
	           '.$trade_type.'
	           '.$sign.'
	         ';
	    //统一接口prepay_id
	    $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
	    $xml = $this->http_request($url,$post_xml);
	    $array = $this->xml($xml);//全要大写
    
	    if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS'){
	        $time = time();
	        $tmp='';//临时数组用于签名
	        $tmp['appId'] = $appid;
	        $tmp['nonceStr'] = $nonce_str;
	        $tmp['package'] = 'prepay_id='.$array['PREPAY_ID'];
	        $tmp['signType'] = 'MD5';
	        $tmp['timeStamp'] = "$time";
	 
	        $data['status'] = true;
	        $data['timeStamp'] = "$time";//时间戳
	        $data['nonceStr'] = $nonce_str;//随机字符串
	        $data['signType'] = 'MD5';//签名算法,暂支持 MD5
	        $data['package'] = 'prepay_id='.$array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
	        $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
	        $data['out_trade_no'] = $out_trade_no;
	 		echo json_encode($data);
	    }else{
	        $data['status'] = false;
	        $data['text'] = "错误";
	        $data['RETURN_CODE'] = $array['RETURN_CODE'];
	        $data['RETURN_MSG'] = $array['RETURN_MSG'];
	        echo json_encode($data);
	    }   	    
	}
下面是一些上述代码需要调用的函数
//随机32位字符串
	private function nonce_str(){
	    $result = '';
	    $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
	    for ($i=0;$i<32;$i++){
	        $result .= $str[rand(0,48)];
	    }
	    return $result;
	}
	//签名 $data要先排好顺序
	private function sign($data){
	    $stringA = '';
	    foreach ($data as $key=>$value){
	        if(!$value) continue;
	        if($stringA) $stringA .= '&'.$key."=".$value;
	        else $stringA = $key."=".$value;
	    }
	    $wx_key = '***************';//这里就是我上面讲解的设置了API的那个密钥 !!!
	    $stringSignTemp = $stringA.'&key='.$wx_key;
	    return strtoupper(md5($stringSignTemp)); 
	}
	private function xml($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;
	}
	private function http_request($url,$data = null,$headers=array())
	{
	    $curl = curl_init();
	    if( count($headers) >= 1 ){
	        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
	    }
	    curl_setopt($curl, CURLOPT_URL, $url);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
	    if (!empty($data)){
	        curl_setopt($curl, CURLOPT_POST, 1);
	        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
	    }
	    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	    $output = curl_exec($curl);
	    curl_close($curl);
	    return $output;
	}

标签:

博览广文网

博览广文网为所有文学爱好者、新闻爱好者、关注生活多方面内容的观众朋友提供多方位的内容呈现、提升阅读空间、填充碎片时间,开阔读者的视野、增长见识、了解民生、一个让您不出户尽知天下事的网站平台!
热门标签
关于我们
广文舒阅网—让天下读者有家可归!这里汇聚了各类优质文化信息,无论是全球热点、历史故事,还是实用百科、趣味探索,您都能轻松获取。我们希望用阅读点亮您的世界,让每一次浏览都充满收获和乐趣。
导航栏A标题
广文舒阅网
扫码关注
联系方式
全国服务热线:0755-88186625
Q Q:8705332
Email:admin@lanyu.com
地址:深圳市福田区海雅缤纷国际大厦5层501
Copyright 深圳市蓝宇科技有限公司 版权所有 备案号:京ICP备20013102号-1