精华内容
下载资源
问答
  • 之前写过一篇文章讲了PHP实现微信支付(jsapi支付)流程 ,详见文章:PHP实现微信支付(jsapi支付)流程。 当时的环境是没有使用框架的,直接在一个域名指向的目录下边新建目录之后访问该目录实现的,但应用到框架中,...
  • 2.ThinkPHP中实现微信支付(jsapi支付)流程 3.PHP实现微信申请退款 这几篇都是使用了微信官方给的PHP版本的SDK,进行支付的时候写代码可以省不少事,步骤也挺简化,但是集成SDK有很多坑,很多人说引入的SDK老报错,...
  • 2.微信支付SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 3.登录微信支付平台https://pay.weixin.qq.com/index.php/account/api_cert下载支付证书 方法步骤: 1.demo文件处理 (1...
  • 微信点金计划公众号支付JSAPI支付后页面自动关闭 https://www.huilianpay.com/forum.php?mod=viewthread&tid=8&fromuid=1
  • tp5微信jsapi支付

    2018-04-17 16:12:01
    thinkphp 5 微信公众号支付 扫码支付 小程序支付 方法封装
  • C# .NETMVC 微信JSAPI支付

    2020-08-28 11:07:36
    C#.NET MVC JSapi微信支付,里面包含页面和控制器的简单代码和示例,结合我上一篇博客来参考的,上一篇博客连接是https://blog.csdn.net/weixin_44486443/article/details/108246514
  • 微信JSAPI公众号支付是素材火群主提供的,支付成功后跳转到订单详情页,里面是微信支付成功后回调的数据,由第三方微信支付平台定时请求获取。
  • net微信扫码支付、手机网页H5支付、微信端JSAPI支付,里面文档有基本的配置
  • 微信JSAPI支付,扫码支付,退款查询接口demo,配置及可直接使用
  • 微信支付完全PHP源码,包Jsapi支付,二维码支付,刷卡支付,订单查询,订单退款,退款查询,订单查询,SDK下载
  • 支付demo,集成了支付宝网站支付,微信jsapi支付,银联网页支付
  • 微信支付apiJSAPI支付 刷卡支付 扫码支付 订单退款 订单查询 退款查询 下载账单
  • jsapi支付和退款.zip

    2019-06-03 21:07:02
    jsapi支付和退款
  • 微信JSAPI支付DEMO PHP版,通俗易懂 包含支付配置文件 发起支付类文件 异步通知类文件 发起支付的HTMl文件等
  • 微信native支付, 微信JSAPI支付, 微信退款, 微信提现, 微信付款查询, 所有方法都已经封装实现, main方法可直接调用体验, maven项目
  • 微信公众号支付-JSAPI支付

    千次阅读 2020-06-01 22:53:58
    JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有: ◆ 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付 ◆ 用户的好友...

    JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:

    ◆ 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
    ◆ 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付
    ◆ 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

    以下是公众号支付的开发流程:实际写的不多,不难的

    注意点:
    提交方式:采用POST方法提交
    API密钥(前面中用到的key):交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按以下路径设置:微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全–>密钥设置
    在这里插入图片描述

    具体步骤:

    1、在JSAPI支付文档的统一下单里看下必须传入的参数

    //  公众账号id
    	private String appid;
    //	商户号
    	private String mch_id;
    //	商品描述
    	private String body;
    //	随机字符串(32位以内)
    	private String nonce_str;
    //	签名(统一下单的所有参数进行签名)
    	private String sign;
    //	商户订单号
    	private String out_trade_no;
    //	标价金额(单位为分)
    	private int total_fee;
    //	终端IP	
    	private String spbill_create_ip;
    //	通知地址
    	private String notify_url;
    //	交易类型
    	private String trade_type;
    //	用户标识(每个用户的openid不一样)
    	private String openid;
    

    2、获取到以上参数后按照以下xml格式发送给文档提供的接口

    <xml>
       <appid>wx2421b1c4370ec43b</appid>
       <attach>支付测试</attach>
       <body>JSAPI支付测试</body>
       <mch_id>10000100</mch_id>
       <detail><![CDATA[{ "goods_detail":[ { "goods_id":"iphone6s_16G", "wxpay_goods_id":"1001", "goods_name":"iPhone6s 16G", "quantity":1, "price":528800, "goods_category":"123456", "body":"苹果手机" }, { "goods_id":"iphone6s_32G", "wxpay_goods_id":"1002", "goods_name":"iPhone6s 32G", "quantity":1, "price":608800, "goods_category":"123789", "body":"苹果手机" } ] }]]></detail>
       <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
       <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
       <openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
       <out_trade_no>1415659990</out_trade_no>
       <spbill_create_ip>14.23.150.211</spbill_create_ip>
       <total_fee>1</total_fee>
       <trade_type>JSAPI</trade_type>
       <sign>0CB01533B8C1EF103065174F50BCA001</sign>
    </xml>
    

    3、返回结果中获取prepay_id,然后进行准备h5调起支付,查看h5调起支付文档,需要参数如下
    在这里插入图片描述
    4、将前面五个参数进行前面后,将六个参数发送到h5页面按照以下格式填入信息,注意成功支付后处理,最好通过文档API到商户后台查询时候已支付完成,然后将结果返回给用户

    function onBridgeReady(){
       WeixinJSBridge.invoke(
          'getBrandWCPayRequest', {
             "appId":"wx2421b1c4370ec43b",     //公众号名称,由商户传入     
             "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
             "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
             "package":"prepay_id=u802345jgfjsdfgsdg888",     
             "signType":"MD5",         //微信签名方式:     
             "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
          },
          function(res){
          if(res.err_msg == "get_brand_wcpay_request:ok" ){
          // 使用以上方式判断前端返回,微信团队郑重提示:
                //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
          } 
       }); 
    }
    if (typeof WeixinJSBridge == "undefined"){
       if( document.addEventListener ){
           document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
       }else if (document.attachEvent){
           document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
           document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
       }
    }else{
       onBridgeReady();
    }
    

    5、到微信支付开发文档的开发步骤里,按照要求到商户后台(登录微信支付商户平台(pay.weixin.qq.com)–>产品中心–>开发配置)和公众号后台网页授权配置域名,
    在这里插入图片描述
    在这里插入图片描述
    6、具体代码如下
    Pay

    public class Pay {
    //  公众账号id
    	private String appid;
    //	商户号
    	private String mch_id;
    //	商品描述
    	private String body;
    //	随机字符串
    	private String nonce_str;
    //	签名
    	private String sign;
    //	商户订单号
    	private String out_trade_no;
    //	标价金额(单位为分)
    	private int total_fee;
    //	终端IP	
    	private String spbill_create_ip;
    //	通知地址
    	private String notify_url;
    //	交易类型
    	private String trade_type;
    //	用户标识
    	private String openid;
    	}
    

    主程序

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Random;
    import java.util.Set;
    import java.util.SortedMap;
    import java.util.TreeMap;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.zz.config.Parameter;
    import com.zz.entity.Pay;
    import com.zz.util.HttpsUtil;
    import com.zz.util.PayUtil;
    import com.zz.util.QRCodeUtil;
    import com.zz.util.Sign;
    import com.zz.util.XStreamUtil;
    import com.zz.util.XmlUtil;
    
    @RestController
    @RequestMapping("pay")
    public class PayController {
    	/**
    	 * JSAPI支付
    	 * @return
    	 */
    	@RequestMapping("jsapiPay")
    	public static Map<String,Object> getJsapiPay(){
    //		openid和金额需要数据库获取
    		String openid="从用户信息中获取";
    		int total_fee=2;
    		
    		String nonce_str=PayUtil.getRandomString(20);
    		String out_trade_no=PayUtil.getCurrentTime()+PayUtil.getRandomString(5);
    		
    		SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
    		parameters.put("appid", Parameter.appID);
    		parameters.put("mch_id", Parameter.mch_id);
    		parameters.put("nonce_str",nonce_str);
    		parameters.put("body", Parameter.body);
    		parameters.put("out_trade_no",out_trade_no);
    		parameters.put("total_fee", total_fee);
    		parameters.put("spbill_create_ip", Parameter.spbill_create_ip);
    		parameters.put("notify_url", Parameter.notify_url);
    		parameters.put("trade_type", Parameter.trade_type);
    		parameters.put("openid", openid);
    		//统一下单签名
    		String prePaySign=Sign.sign(parameters);
    
    		Pay pay = new Pay();
    		pay.setAppid(Parameter.appID);
    		pay.setMch_id(Parameter.mch_id);
    		pay.setNonce_str(nonce_str);
    		pay.setBody(Parameter.body);
    		pay.setOut_trade_no(out_trade_no);
    		pay.setTotal_fee(total_fee);
    		pay.setSpbill_create_ip(Parameter.spbill_create_ip);
    		pay.setNotify_url(Parameter.notify_url);
    		pay.setTrade_type(Parameter.trade_type);
    		pay.setOpenid(openid);
    		pay.setSign(prePaySign);
    		//生成xml格式
    		XStreamUtil.xstream.alias("xml", Pay.class);
    		String xml = XStreamUtil.xstream.toXML(pay).replaceAll("__", "_");
    		
    		System.out.println(xml);
    		
    		String prepay_id=null;
    		try {
    			String resXml=HttpsUtil.httpsRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", xml);
    			prepay_id=XmlUtil.parseXml(resXml, "prepay_id");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		//微信内h5调起支付
    		String timeStamp= PayUtil.getTimeStamp();
    		String Package="prepay_id="+prepay_id;
    		SortedMap<Object,Object> h5parameters = new TreeMap<Object,Object>();
    		h5parameters.put("appId", Parameter.appID);
    		h5parameters.put("timeStamp",timeStamp);
    		h5parameters.put("nonceStr", nonce_str);
    		h5parameters.put("package",Package);
    		h5parameters.put("signType", "MD5");
    		String paySign=Sign.sign(h5parameters);
    		
    		Map<String,Object> map = new HashMap<String,Object>();
    		map.put("appId", Parameter.appID);
    		map.put("timeStamp", timeStamp);
    		map.put("nonceStr", nonce_str);
    		map.put("package", Package);
    		map.put("signType", "MD5");
    		map.put("paySign", paySign);
    		
    		return map;
    	}
    
    
    /**
    	 * 扫码/JSAPI支付回调
    	 * 
    	 * @param request
    	 * @return
    	 * @throws NumberFormatException
    	 * @throws Exception
    	 */
    	@RequestMapping("dealwith")
    	public String dealwith(HttpServletRequest request) throws NumberFormatException, Exception {
    		//获取回调信息
    		InputStream inputStream=null;
    		inputStream=request.getInputStream();
    		StringBuffer sb=new StringBuffer();
    		BufferedReader in=new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
    		String s;
    		while(null!=(s=in.readLine())){
    			sb.append(s);
    		}
    		in.close();
    		inputStream.close();
    		String resXml=sb.toString();
    		System.out.println("------------:"+resXml);
    		
    		// 解析xml成map
    		Map<String,String> map = new HashMap<>();
    		map = XmlUtil.parseAllXml(resXml);
    		
    		//设置 TreeMap
    		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
    		packageParams.putAll(map);
    		
    		// 判断签名是否正确
    		Boolean isSign=Sign.isSign(packageParams);
    		if(isSign){
    			// ------------------------------
    			// 处理业务开始
    			// ------------------------------
    			if ("SUCCESS".equals(XmlUtil.parseXml(resXml, "result_code"))) {
    				System.out.println("支付成功");
    				//顾客具体信息,地址存入数据库,提供发货,通知用户下单成功
    				//向工作人员发送支付成功消息等(消息回复,模板消息)
    				// 执行自己的业务逻辑
    
    				System.out.println("验签成功");
    				String orderId = (String) packageParams.get("out_trade_no");
    				String transactionId = (String) packageParams.get("transaction_id");
    				if (orderId != null) {
    //					ReturnBody body = orderService.pay(orderId, transactionId, "微信支付");
    				}
    
    				// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
    				resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
    						+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
    
    			} else {
    				System.out.println("支付失败,错误信息:" + packageParams.get("err_code"));
    				resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
    						+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
    			}
    			// ------------------------------
    			// 处理业务完毕
    			// ------------------------------
    			return resXml;
    		} else {
    			System.out.println("通知签名验证失败");
    		}
    		return "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
    		 + "<return_msg><![CDATA[OK]]></return_msg>"+"</xml>";
    	}
    	}
    

    html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script type="text/javascript" src="js/pay.js"></script>
    </head>
    <body>
    
    </body>
    </html>
    

    js`

    $(document).ready(function(){
    	
    	 $.getJSON("pay/prePay/",function(json){
    		 console.log(json);
    		 console.log(json.appId);
    		 var appId=json.appId;
    		 var timeStamp=json.timeStamp;
    		 var nonceStr=json.nonceStr;
    		 var package1=json.package;
    		 var signType=json.signType;
    		 var paySign=json.paySign;
    		 pay();
    		 
    		 function onBridgeReady(){
    		        WeixinJSBridge.invoke(
    			      'getBrandWCPayRequest', {
    			         "appId":appId,            //公众号名称,由商户传入     
    			         "timeStamp":timeStamp,    //时间戳,自1970年以来的秒数     
    			         "nonceStr":nonceStr,      //随机串     
    			         "package":package1,     
    			         "signType":"MD5",         //微信签名方式:     
    			         "paySign":paySign         //微信签名 
    			      },
    			      function(res){
    			      if(res.err_msg == "get_brand_wcpay_request:ok" ){
    			          // 使用以上方式判断前端返回,微信团队郑重提示:
    			          //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
    			    	  //这里填写支付之后的页面跳转(一般要根据API查询接口到商户后台查询结果,然后在该页面显示)
    			    	  window.location.href="test.html";
    			      } else{
    			    	  question = confirm("支付失败,是否重新支付");
    			    	  if(question){
    			    		  pay();
    			    	  }
    			      }
    			   }); 
    	 		}
    		 
    		 
    		 function pay(){
    			 if (typeof WeixinJSBridge == "undefined"){
    				   if( document.addEventListener ){
    				       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
    				   }else if (document.attachEvent){
    				       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
    				       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
    				   }
    				}else{
    				   onBridgeReady();
    				}
    			}
    	 })
    	
    
    })
    

    支付链接:

    http://域名/pay.html
    
    展开全文
  • 最近接触到一个项目,涉及到...2.微信支付SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 3.登录微信支付平台https://pay.weixin.qq.com/index.php/account/api_cert下载支付证书...

    最近接触到一个项目,涉及到微信支付,搞微信开发这么久以来,还没搞过支付,之前也就搞过公众号发红包,感谢前辈们的探索,我看了他们的博文,让我少走了很多弯路。 

    前期准备: 
    1.微信认证服务号,并且开通了微信支付 
    2.微信支付SDK,下载地址: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 
    3.登录微信支付平台 https://pay.weixin.qq.com/index.php/account/api_cert下载支付证书 

    方法步骤: 
    1.demo文件处理 
    (1)将官方的demo下载下来,文件名为WxpayAPI_php_v3,把这文件重命名为wxpay,为了后边书写目录方便; 

    (2)打开lib文件夹下的WxPay.Api.php文件,在537行有一段curl网络请求配置代码:

    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验

    替换成:

    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验

    为了禁止 cURL 验证对等证书(peer's certificate)。

     

    (3)打开lib文件夹下的WxPay.Config.php文件,第25行开始,根据自己的账号完成基本信息设置;

    const APPID = '公众账号APPID';const MCHID = '商户号';const KEY = '商户支付密钥';const APPSECRET = '公众帐号secert';

    (4)打开lib文件夹下的WxPay.Notify.php文件,第79行的代码:

    if($needSign == true &&	$this->GetReturn_code($return_code) == "SUCCESS"){	$this->SetSign();}

    改成:

     

    if($needSign == true &&	$this->GetReturn_code() == "SUCCESS"){	$this->SetSign();}

    (5)打开cert证书目录,将里边的两个证书换成自己的支付证书。

     

    2.公众号后台设置 

    (1)配置网页授权域名,我的域名是(xy.chuyin.ren);

    (1)配置支付授权目录,域名是(xy.chuyin.ren),我将demo放到此域名指向的目录的weixinopen/文件夹下,demo中jsapi.php文件位于example/目录下,所以支付授权目录为:xy.chuyin.ren/weixinopen/wxpay/example/

    3.支付流程 
    打开example目录下的jsapi.php文件,支付发起和处理,都是在这里完成。 
    (1)获取用户openid 

    之前配置好了自己的APPID和APPSecert,所以这里不用处理。

    //①、获取用户openid$tools = new JsApiPay();$openId = $tools->GetOpenid();

    这里首先初始化的一个JsApiPay()类得到一个对象,文件对应example/目录下的WxPay.JsApiPay.php,调用GetOpenid()方法,会自动获取自己的openID。

     

    (2)统一下单

    //②、统一下单$input = new WxPayUnifiedOrder();$input->SetBody("test");$input->SetAttach("test");$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));$input->SetTotal_fee("1");$input->SetTime_start(date("YmdHis"));$input->SetTime_expire(date("YmdHis", time() + 600));$input->SetGoods_tag("test");$input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");$input->SetTrade_type("JSAPI");$input->SetOpenid($openId);$order = WxPayApi::unifiedOrder($input);echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';printf_info($order);$jsApiParameters = $tools->GetJsApiParameters($order);

    对应WxPay.Api.php的第24行的unifiedOrder()方法,配置订单信息和支付回调函数,这里需要修改几个参数:

     

    A. 商品名称:

    $input->SetBody("test");

    B. 订单号

    $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));

    C. 支付金额

    $input->SetTotal_fee("1");

    D. 支付验证链接

    设置为你的notify.php文件所在的位置,所以我这里设置为:http://xy.chuyin.ren/weixinopen/wxpay/example/notify.php

    也可以写其他地址,当然要在支付授权域名之下,支付成功之后就会自动回调到该链接指定的方法里边,可以在里边进行判断和数据库操作.

    $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php");

    E. 附加参数

    $input->SetAttach("test");

     

    附加参数,可填可不填,填写的话,里边字符串最好不要出现空格。 
    这时候,点击支付应该就可以成功支付了。 

    (3)发起支付

    <script type="text/javascript">//调用微信JS api 支付function jsApiCall(){	WeixinJSBridge.invoke(		'getBrandWCPayRequest',		<?php echo $jsApiParameters; ?>,		function(res){			WeixinJSBridge.log(res.err_msg);			alert(res.err_code+res.err_desc+res.err_msg);		}	);}function callpay(){	if (typeof WeixinJSBridge == "undefined"){		if( document.addEventListener ){			document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);		}else if (document.attachEvent){			document.attachEvent('WeixinJSBridgeReady', jsApiCall);			document.attachEvent('onWeixinJSBridgeReady', jsApiCall);		}	}else{		jsApiCall();	}}</script>

    点击立即支付按钮调用的就是 callpay() 函数,他有会调用jsApiCall() 函数打开支付程序。

     

    jsApiCall() 函数会监听每一步动作:

     res.err_msg 为get_brand_wcpay_request:cancel 表明前端判断的取消支付,es.err_msg 为get_brand_wcpay_request:ok 表明前端判断的支付成功,我们可以根据这个将支付跳转到成功页面。

    (4)支持成功回调 

    通过前端jsApiCall()函数可以监听支付结果,但是这个并不可信。确认是否支付成功还是应当通过notify.php 处理业务逻辑。前边配置好了支付验证链接SetNotify_url(),支付完成后,微信服务器会根据链接自动请求你的notify.php文件,打开这个文件,其实这个文件最主要的代码就两行:

    $notify = new PayNotifyCallBack();$notify->Handle(false);

    由此跟踪到WxPay.Notify.php类文件的Handle()函数:

    /** *  * 回调入口 * @param bool $needSign  是否需要签名输出 */final public function Handle($needSign = true){	$msg = "OK";	//当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败	$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);	if($result == false){		$this->SetReturn_code("FAIL");		$this->SetReturn_msg($msg);		$this->ReplyNotify(false);		return;	} else {		//该分支在成功回调到NotifyCallBack方法,处理完成之后流程		$this->SetReturn_code("SUCCESS");		$this->SetReturn_msg("OK");	}	$this->ReplyNotify($needSign);}

    主要代码:

    $result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);

    然后来到WxPay.Api.php文件的第411行,notify()函数:

    /** *  * 支付结果通用通知 * @param function $callback * 直接回调函数使用方法: notify(you_function); * 回调类成员函数方法:notify(array($this, you_function)); * $callback  原型为:function function_name($data){} */public static function notify($callback, &$msg){	//获取通知的数据	$xml = $GLOBALS['HTTP_RAW_POST_DATA'];	//file_put_contents('log.txt',$xml,FILE_APPEND);	//如果返回成功则验证签名	try {		$result = WxPayResults::Init($xml);	} catch (WxPayException $e){		$msg = $e->errorMessage();		return false;	}		return call_user_func($callback, $result);}

    这里面的$xml=$GLOBALS['HTTP_RAW_POST_DATA'],就是支付成功后用户返回给你的一个结果,他是一个xml格式的字符串。

     

    我们可以将这里返回的xml数据记录下来,然后打开看看$out_trade_no就是在支付之前我自己设置的订单号码,$attach就是设置的附加参数。

    得到了这个订单号,然后我就直接在下面写支付成功后的逻辑了,比如改变数据库中的数据等等。

    这样 微信支付的 JsApi支付就大致分析完成了。

    这是集成了官方的SDK实现的,如果不使用SDK,可以使用更简单的方法,见:PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)

    展开全文
  • 服务号开通的微信支付的认证 腾讯给你的邮件中有商户登录的账号和密码 拥有一个可供上传代码和设置回调域名的网站或云服务 有一点点php知识。 开通了认证后的服务号服务号开通的微信支付的认证腾讯给你的邮件中...
  • 目录标题微信支付之扫码Native支付与JSAPI支付进入主题一、Native支付1. 使用场景2. 开发步骤3. 开始开发二、JSAPI支付1. 使用场景2. 开发步骤3. 开始开发 微信支付之扫码Native支付与JSAPI支付 在电商网站开发中,...

    微信支付之扫码Native支付与JSAPI支付

    在电商网站开发中,我们必不可少的功能环节就是“支付”了,我们可以根据公司或者自己的开发需求,选择不一样的支付方式,比如微信支付,支付宝支付,银联支付,以及跨境支付如PayPal等等的众多方式供你选择,今天,我将和大家聊聊微信支付之二微信扫码Native支付与微信JSAPI支付。

    进入主题

    根据微信官方提供的文档,我们来进行梳理。首先我们访问:微信支付-开发文档
    进入如下界面:

    在这里插入图片描述

    一、Native支付

    1. 使用场景

    我们首先会调用微信提供的API得到二维码链接,这个链接可以通过前端qrcode.js将链接转换为二维码,也可以在后台通过谷歌的ZXing工具生成二维码。详细介绍如下:

    在这里插入图片描述

    2. 开发步骤

    首先,你需要在微信支付的商户平台配置扫码支付的回调域名,具体位置为:商户平台–>产品中心–>开发配置。

    在这里插入图片描述

    当然,你也可以不用配置扫码支付的回调地址,而是在调用微信支付的统一下单API接口中传递参数notify_url。我选的是这种方式,可以将回调配置在yml文件中,自由定义,不需要关心商户平台的回调地址。

    在这里插入图片描述

    最后,还需要选择一种模式,我采用的是模式二,你也可以根据自己的需求,选择你认为合适的开发模式。如下图模式二说明了接下来我们编码的流程:

    在这里插入图片描述

    在这里插入图片描述

    3. 开始开发

    (1)商户后台系统根据用户选购的商品生成订单。

    用户在商城平台提交订单,我们会生成初始订单。

    在这里插入图片描述

    商城平台生成订单之后,接着调用微信支付。进行第二,第三步骤,如下:

    (2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;

    这一步骤,有一个关键的地方是生成商户单号。如下是我生成商户单号的方式。

    在这里插入图片描述

    生成商户单号

    @Override
        @Transactional(rollbackFor = Exception.class)
        public String generateCode(KeSequence.Tag tag,  String userMobile) {
            Long sequence = this.findSequence(Long.parseLong(tag.getCode()+""));
    
            this.updateSequence(Long.parseLong(tag.getCode()+""),sequence);
    
            return DateWithRandomUtils.numsToRandom()+ sequence+ ((userMobile.length()>4)?(userMobile.substring(userMobile.length()-4)):userMobile);
        }
    

    调用工具方法

    /**
         * 将生成的时间+num位随机数,打乱
         * @return
         */
        public static String numsToRandom(){
            String randomNO = randomNO(4);
            char[] chars = randomNO.toCharArray();
            List<String> list = new ArrayList<>();
            for (char aChar : chars) {
                list.add(aChar+"");
            }
            Collections.shuffle(list);
    
            StringBuffer sb = new StringBuffer();
            list.forEach(ch->{
                sb.append(ch);
            });
            return sb.toString();
        }
    

    工具方法细节:

    /**
         * 唯一编号 = 点前时间年月日时分秒+num位随机数
         * @return
         */
        public static String randomNO(int num){
            String newsNo = timeNoYMDHMS();
            long random = getRandom(num);
            return newsNo+random;
        }
    
        /**
         * 获取当前时间 yyyyMMddHHmmss
         * @return
         */
        public static  String timeNoYMDHMS(){
            //设置日期格式
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
            // new Date()为获取当前系统时间,也可使用当前时间戳
            String newsNo = df.format(new Date());
            return newsNo;
        }
        /**
         * 生成固定长度随机码
         * @param n    长度
         */
        public static long getRandom(long n) {
            long min = 1,max = 9;
            for (int i = 1; i < n; i++) {
                min *= 10;
                max *= 10;
            }
            long rangeLong = (((long) (new Random().nextDouble() * (max - min)))) + min ;
            return rangeLong;
        }
    

    (3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。

    生成商户单号,接着可以通过微信提供的SDK,调用统一下单的方法了,我的做法如下:

    核心代码:

    /**
         * 微信支付
         * @param keOrder
         * @return
         */
        private ResultMsg WxUnifiedorder(KeOrder keOrder,String bizPayNo, Integer tradeType, String openid) throws Exception {
            //设置需要的参数
            WxParamQuery wxParamQuery = new WxParamQuery();
            //是
            wxParamQuery.setOut_trade_no(bizPayNo);
            //以分为单位
            wxParamQuery.setTotal_fee(keOrder.getActualTotal().multiply(BigDecimal.valueOf(100)).longValue()+"");
            String body = "";
            if(!StringUtils.isEmpty(keOrder.getProdName())){
                body = keOrder.getProdName().length()>15 ? keOrder.getProdName().substring(0,15)+"...":keOrder.getProdName();
            }
            wxParamQuery.setBody(body);
            wxParamQuery.setReceipt("N");
            // 注意:此处配置交易方式, JSPAI, NATIVE...
            wxParamQuery.setTrade_type(WxParamQuery.getTradeTypeMap(tradeType));
            //否
            wxParamQuery.setAttach(keOrder.getOrderNo());
            wxParamQuery.setProduct_id("");
            wxParamQuery.setOpenid(openid);
            wxParamQuery.setDetail("");
            wxParamQuery.setDevice_info("WEB");
            wxParamQuery.setUserId(keOrder.getUserId());
    
    
            return wxPayService.unifiedorder(wxParamQuery);
        }
    

    调用统一下单API:

    /**
         * 微信支付-统一下单
         * @param wxParamQuery
         * @return
         */
        @Override
        @Transactional
        public ResultMsg unifiedorder(WxParamQuery wxParamQuery) throws Exception {
            Map<String,String> data = new ConcurrentHashMap();
            data.put("device_info",wxParamQuery.getDevice_info());
            data.put("body",wxParamQuery.getBody());
            data.put("detail",wxParamQuery.getDetail());
            data.put("attach",wxParamQuery.getAttach());
            data.put("out_trade_no",wxParamQuery.getOut_trade_no());
            data.put("total_fee",wxParamQuery.getTotal_fee());
            data.put("trade_type",wxParamQuery.getTrade_type());
            data.put("product_id",wxParamQuery.getProduct_id());
            data.put("openid",wxParamQuery.getOpenid());
            data.put("receipt",wxParamQuery.getReceipt());
            data.put("spbill_create_ip", spbill_create_ip);
    
            if("JSAPI".equalsIgnoreCase(wxParamQuery.getTrade_type())){
                if(StringUtils.isEmpty(wxParamQuery.getOpenid())){
                    return ResultMsg.fail("缺少参数openid",null);
                }
            }
    
            try {
                WXPayConfig payConfig =  new PayConfig(appID,mchID,key,domain,primaryDomain, true);
                WXPay wxPay = new WXPay(payConfig,notify_url,true,false);
                data = wxPay.fillRequestData(data);
    
                //微信提供的统一下单方法一:
                Map<String,String> resMap = wxPay.unifiedOrder(data);
    
                //主动调微信统一下单方法二
                /*
                String xml = WXPayUtil.mapToXml(data);
                String res = HttpHelper.post(pay_url, xml, "text/plain;charset=UTF-8");
                Map<String, String> resMap = WXPayUtil.xmlToMap(res);
                */
    
                if("SUCCESS".equalsIgnoreCase(resMap.get("return_code"))){
                    if("SUCCESS".equalsIgnoreCase(resMap.get("result_code"))){
                        // 获取二维码链接
                        String code_url = resMap.get("code_url");
                        String prepay_id = resMap.get("prepay_id");
                        Map<String, String> payParam = wxUtils.getJsapiPayParam(prepay_id);
                        if(wxParamQuery.getTrade_type().equals(WxParamQuery.TradeType.NATIVE.name())){
                            return ResultMsg.suc(code_url);
                        }else{
                            return ResultMsg.suc(payParam);
                        }
                    }
                }
                String return_msg = resMap.get("return_msg");
                return ResultMsg.fail(return_msg,return_msg);
    
            } catch (Exception e) {
                e.printStackTrace();
                return ResultMsg.fail(e.getMessage(),e.getMessage());
            }
        }
    

    调用成功之后,微信会返回code_url, 二维码链接,至此,我们可以将二维码链接转换为二维码图片,即可。

    当用户扫码支付完成之后,会进入回调,我们可以在回调中修改订单的状态或者其他必要的操作。如下,是我的回调代码。

    核心代码:

    @RequestMapping(value = "/notifyUrl")
        public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
            String resXml = "";
            try {
                log.info("微信notifyUrl回调方法,开始进入。。。");
    
                //读取参数
                StringBuffer sb = new StringBuffer();
                InputStream inputStream = request.getInputStream();
                BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                String str = null ;
                while ((str = in.readLine()) != null){
                    sb.append(str);
                }
                in.close();
                inputStream.close();
    
    
                //解析xml成map
                Map<String, String> m = WXPayUtil.xmlToMap(sb.toString());
    
    
                //过滤空 设置 TreeMap
                SortedMap<String,String> packageParams = new TreeMap<>();
                Iterator<String> it = m.keySet().iterator();
                while (it.hasNext()) {
                    String parameter = it.next();
                    String parameterValue = m.get(parameter);
    
                    String v = "";
                    if(null != parameterValue) {
                        v = parameterValue.trim();
                    }
                    packageParams.put(parameter, v);
                }
                log.info("微信支付返回回来的参数:"+packageParams);
    
                try {
                    // 支付日志入库
                    iKePayLogService.saveWxPayLog(packageParams);
                }catch (Exception e){
                    e.printStackTrace();
                }
    
    
                //判断签名是否正确
                if(WXPayUtil.isSignatureValid(m, key, WXPayConstants.SignType.HMACSHA256)) {
                    //------------------------------
                    //处理业务开始
                    //------------------------------
    
                    if("SUCCESS".equalsIgnoreCase( packageParams.get("return_code")) &&
                            "SUCCESS".equals(packageParams.get("result_code"))){
                        // 这里是支付成功
                        //执行自己的业务逻辑开始
                        String app_id = packageParams.get("appid");
                        String mch_id = packageParams.get("mch_id");
                        String openid = packageParams.get("openid");
                        //是否关注公众号
                        String is_subscribe = packageParams.get("is_subscribe");
    
                        //附加参数【订单号】
                        String attach = packageParams.get("attach");
                        //商户订单号
                        String out_trade_no = packageParams.get("out_trade_no");
    
                        //付款金额【以分为单位】
                        String total_fee = packageParams.get("total_fee");
    
                        //微信生成的交易订单号
                        String transaction_id = packageParams.get("transaction_id");
    
                        //支付完成时间
                        String time_end= packageParams.get("time_end");
    
                        log.info("app_id:"+app_id);
                        log.info("mch_id:"+mch_id);
                        log.info("openid:"+openid);
                        log.info("is_subscribe:"+is_subscribe);
                        log.info("out_trade_no:"+out_trade_no);
                        log.info("total_fee:"+total_fee);
                        log.info("额外参数_attach:"+attach);
                        log.info("time_end:"+time_end);
    
    
                        //执行自己的业务逻辑开始
                        log.info("支付成功。。。执行自己的业务逻辑开始");
                        OrderPayDTO orderPayDTO = new OrderPayDTO();
                        orderPayDTO.setTransaction_id(transaction_id);
                        orderPayDTO.setOut_trade_no(out_trade_no);
                        orderPayDTO.setMch_id(mch_id);
                        orderPayDTO.setApp_id(app_id);
                        orderPayDTO.setAttach(attach);
                        orderPayDTO.setTime_end(LocalDateTime.now());
                        orderPayDTO.setOpenid(openid);
                        orderPayDTO.setIs_subscribe(is_subscribe);
                        orderPayDTO.setTotal_fee(BigDecimal.valueOf(Double.parseDouble(total_fee)));
                        orderPayDTO.setPayType(KeOrder.orderPayType.WECHAT_PAY.getCode());
    
                        //调用业务处理方法
                        iKeOrderService.orderPaySuc(orderPayDTO);
                        //执行自己的业务逻辑结束
    
                        //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                        resXml = notifyToWx("SUCCESS","OK");
    
                    } else {
                        log.info("支付失败,错误信息:" + packageParams.get("err_code"));
                        resXml = notifyToWx("FAIL",packageParams.get("err_code"));
                    }
    
                } else{
                    resXml = notifyToWx("FAIL","签名验证失败");
                }
            }catch (Exception e){
                e.printStackTrace();
                resXml = notifyToWx("FAIL","程序异常");
            }
    
            //------------------------------
            //处理业务完毕
            //------------------------------
            BufferedOutputStream out = new BufferedOutputStream(
                    response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        }
    
    
    
        public String notifyToWx(String return_code, String return_msg){
            return "<xml>" + "<return_code><![CDATA["+return_code+"]]></return_code>"
                    + "<return_msg><![CDATA["+return_msg+"]]></return_msg>" + "</xml> ";
        }
    

    二、JSAPI支付

    JSAPI支付的后端实现逻辑和Native之后一样,只需要多传入一个必传参数openid,上面已经列举,我就不必再次重复说明了。 接下来,我将说明和Native不同的实现逻辑。

    1. 使用场景

    我们开发公众号时,需要调用微信支付,这时候就是需要JSPAPI支付了,JSAPI需要通过网页授权,获取用户的openid,也就是上述步骤中调用微信的统一下单需要的步骤,然后再改变trade_type为JSAPI,如下
    在这里插入图片描述
    其余步骤与Native一致。

    在这里插入图片描述

    2. 开发步骤

    JSAPI支付必须要在商户平台配置支付目录,所谓支付目录就是指:前端调起微信支付的当前URL地址。 设置如下:

    在这里插入图片描述

    3. 开始开发

    调起支付,需要配置jsconfig,我用的是vue, 以下我将介绍vue的方式发起支付。
    首先前端配置如下:

    mounted() {
        this.axios
          .get(
            "/kuais/essleyWeb/essley/wx/getWxConfigParams",
            {
              params: {
                webUrl: this.webUrl
              }
            }
          )
          .then(res => {
            var data = res.data.data;
              console.log(data)
            wx.config({
              debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
              appId: data.appId, // 必填,公众号的唯一标识
              timestamp: data.timestamp, // 必填,生成签名的时间戳
              nonceStr: data.nonceStr, // 必填,生成签名的随机串
              signature: data.signature, // 必填,签名,见附录1
              jsApiList: ["chooseWXPay"]
            });
            wx.ready(function() {
              wx.checkJsApi({
                jsApiList: ["chooseWXPay"],
                success: function(res) {
                  console.log("seccess");
                  console.log(res);
                },
                fail: function(res) {
                  console.log("fail");
                  console.log(res);
                }
              });
            });
          });
      },
    

    我们需要在后端,获取token,然后获取jsapi_ticket。 得到初始化参数之后,返回给前端,配置jsconfig。 可以通过微信开发者工具中查看是否配置成功,(有时候你看JS-SDK中提示签名错误,其实也是可以调起微信支付的)。 代码如下:

    /**
         * 签名算法
         签名生成规则如下:参与签名的字段包括noncestr(随机字符串),
         有效的jsapi_ticket, timestamp(时间戳),
         url(当前网页的URL,不包含#及其后面部分) 。
         对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,
         使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
         这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
         */
        public Map<String,String> wxConfigParams(String webUrl){
            String jsapi_ticket = jsapiTicketFromRedis();
            String noncestr = WXPayUtil.generateNonceStr();
            String timestamp = WXPayUtil.getCurrentTimestamp()+"";
            String url = webUrl;
    
            String[] arr = new String[]{jsapi_ticket,noncestr, timestamp,url};
            String string1 = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
    
            log.info("拼接好的string1: "+string1);
            String sha1Hex = DigestUtils.sha1Hex(string1.getBytes());
    
            log.info("jsapi_ticket签名:  "+sha1Hex);
    
            Map<String,String> resMap = new HashMap<>();
            resMap.put("appId", WebAppID);
            resMap.put("timestamp", timestamp);
            resMap.put("nonceStr", noncestr);
            resMap.put("signature", sha1Hex);
    
            return resMap;
        }
    

    jsconfig配置成功之后,接下来就可以调用微信统一下单API了, 与Native扫码支付不同的是,它需要返回如下参数:

    appId: data.appId,
    timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    nonceStr: data.nonceStr, // 支付签名随机串,不长于 32
    package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
    signType: data.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
    paySign: data.paySign, // 支付签名
    

    如果后端返回的参数没有问题,这时候,就可以发起微信支付了。输入密码,就可以支付完成。

    展开全文
  • 3.要设置 JSAPI支付 支付授权目录(微信支付->产品中心->开发配置->支付配置->JSAPI支付授权目录,设置域名就可以) 方法步骤: 1.解压下载的demo文件夹改名为WxpayJSAPI(自己命名),整个复制到核心...

    前期准备:

    1.微信认证服务号,并且开通了微信支付
    2.微信支付SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
    3.要设置 JSAPI支付 支付授权目录(微信支付->产品中心->开发配置->支付配置->JSAPI支付授权目录,设置域名就可以)

    在这里插入图片描述

    方法步骤:

    1.解压下载的demo文件夹改名为WxpayJSAPI(自己命名),整个复制到核心框架ThinkPHP\Library\Vendor中方便调用。
    在这里插入图片描述

    2.将example以及lib中的文件,引入外部文件require_once的路径修改,类似于require_once “…/” 的路径全部改成下图所示。
    在这里插入图片描述

    3.编写支付的控制器以及视图,比如 我写的是控制器TestController,方法是wxJsApiTest页面,大部分代码是demo里面的。

     public function wxJsApiTest()
        {
    
            /**
             *
             * example目录下为简单的支付样例,仅能用于搭建快速体验微信支付使用
             * 样例的作用仅限于指导如何使用sdk,在安全上面仅做了简单处理, 复制使用样例代码时请慎重
             * 请勿直接直接使用样例对外提供服务
             *
             **/
            vendor('WxpayJSAPI.example.WxPay#JsApiPay');//引入文件
            header("Content-Type: text/html;charset=utf-8");
    		//①、获取用户openid
            try{
                $tools =  new \JsApiPay();
                $openId = $tools->GetOpenid();
                //②、统一下单
                $input = new \WxPayUnifiedOrder();
                $input->SetBody("test");
                $input->SetAttach("test");
                $input->SetOut_trade_no("sdkphp".date("YmdHis"));
                $input->SetTotal_fee("1");
                $input->SetTime_start(date("YmdHis"));
                $input->SetTime_expire(date("YmdHis", time() + 600));
                $input->SetGoods_tag("test");
                $input->SetNotify_url("http://www.xxxx.com/Home/Test/huidiaojsapi");
                $input->SetTrade_type("JSAPI");
                $input->SetOpenid($openId);
                $config = new \WxPayConfig();
                $order = \WxPayApi::unifiedOrder($config, $input);
                echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>';
                $this->printf_info($order);
                $jsApiParameters = $tools->GetJsApiParameters($order);
    
                //获取共享收货地址js函数参数
                $editAddress = $tools->GetEditAddressParameters();
            } catch(Exception $e) {
                //Log::ERROR(json_encode($e));
            }
    //③、在支持成功回调通知中处理成功之后的事宜,见 notify.php
            /**
             * 注意:
             * 1、当你的回调地址不可访问的时候,回调通知会失败,可以通过查询订单来确认支付是否成功
             * 2、jsapi支付时需要填入用户openid,WxPay.JsApiPay.php中有获取openid流程 (文档可以参考微信公众平台“网页授权接口”,
             * 参考http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)
             */
             return $this->render('Test:wxJsApiZf', array(
                    'openid'    => 123,
                    'jsApiParameters' =>$jsApiParameters,
                    'editAddress' => $editAddress
          ));
        }
    //打印输出数组信息
        public function printf_info($data)
        {
            foreach($data as $key=>$value){
                echo "<font color='#00ff55;'>$key</font> :  ".htmlspecialchars($value, ENT_QUOTES)." <br/>";
            }
        }
    

    视图:(截取了部分代码,根据自己的需求进行美化,大部分也是demo里面的)

    <html>
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <title>微信支付样例-支付</title>
        <script type="text/javascript">
            //调用微信JS api 支付
            function jsApiCall()
            {
                var jsApiParameters = "{{ jsApiParameters }}".replace( /&quot;/g, '"' );
                jsApiParameters = JSON.parse(jsApiParameters);
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest',{
                        "appId":jsApiParameters.appId,     //公众号名称,由商户传入
                        "timeStamp":jsApiParameters.timeStamp,         //时间戳,自1970年以来的秒数
                        "nonceStr":jsApiParameters.nonceStr, //随机串
                        "package":jsApiParameters.package,
                        "signType":jsApiParameters.signType,         //微信签名方式:
                        "paySign":jsApiParameters.paySign //微信签名
                    },
                function(res){
                    if(res.err_msg === 'get_brand_wcpay_request:ok'){
                        alert("支付成功");
                    }else if(res.err_msg === 'get_brand_wcpay_request:cancel'){
                        alert("取消支付!");
                    }
                }
            );
            }
    
            function callpay()
            {
                if (typeof WeixinJSBridge == "undefined"){
                    if( document.addEventListener ){
                        document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
                    }else if (document.attachEvent){
                        document.attachEvent('WeixinJSBridgeReady', jsApiCall);
                        document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                    }
                }else{
                    jsApiCall();
                }
            }
        </script>
    </head>
    <body>
    <br/>
    <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span></b></font><br/><br/>
    <div align="center">
        <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
    </div>
    </body>
    </html>
    

    访问页面
    http://test.xxxx.com/Home/Test/wxJsApiTest
    要用真机调试,微信开发者工具 只能看样式
    在这里插入图片描述

    回调 这里配置回调路径
    在这里插入图片描述

    在这里插入图片描述

    回调内容

    <xml>
      <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
      <attach><![CDATA[支付测试]]></attach>
      <bank_type><![CDATA[CFT]]></bank_type>
      <fee_type><![CDATA[CNY]]></fee_type>
      <is_subscribe><![CDATA[Y]]></is_subscribe>
      <mch_id><![CDATA[10000100]]></mch_id>
      <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
      <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
      <out_trade_no><![CDATA[1409811653]]></out_trade_no>
      <result_code><![CDATA[SUCCESS]]></result_code>
      <return_code><![CDATA[SUCCESS]]></return_code>
      <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
      <time_end><![CDATA[20140903131540]]></time_end>
      <total_fee>1</total_fee>
      <coupon_fee><![CDATA[10]]></coupon_fee>
      <coupon_count><![CDATA[1]]></coupon_count>
      <coupon_type><![CDATA[CASH]]></coupon_type>
      <coupon_id><![CDATA[10000]]></coupon_id>
      <trade_type><![CDATA[JSAPI]]></trade_type>
      <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
    </xml>
    

    遇到的问题,记下来供大家参考。

    (1)curl出错 错误码:60
    解决方法:在WxPay.Api.php文件中

    //找到以下两行代码:
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
    //改成
    if(stripos($url,"https://")!==FALSE){
        curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    }else{
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
    }
    

    (2)URL未注册
    解决方法:
    首先确定了支付授权目录设置没有问题,最后发现是URL_MODEL 为pathinfo 的问题,一开始我写的跳转到支付的页面的网址形式是这种http://xxx.com/Weixinpay/index/id/1 ,其实我们认为Weixinpay是目录而已,后面是文件,id是参数,但微信认为是到最后一个斜杠为止都是目录,也就是id,最后我改成了http://xxx.com/Weixinpay/index?id=1,测试成功。
    (3)errMsg: “chooseWXPay:fail, the permission value is offline verifying”
    解决办法:
    要用真机调试
    (4)errMsg":“translateVoice:fail, the permission value is offline verifying”
    解决办法:
    自己写的参数,没有使用原来的直接放参数

    在这里插入图片描述

    在这里插入图片描述

    备注

    参考支付:
    https://blog.csdn.net/wyy20/article/details/104601665
    支付结果通知
    https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
    业务流程
    https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4
    支付常见问题
    https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=7_9&index=7

    展开全文
  • 微信支付之JSAPI支付

    千次阅读 2018-12-06 16:10:22
    JSAPI支付 JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付 使用场景 用户在微信公众账号(必须是服务号)内进入商家公众号,打开某个H5页面,...
  • 返显信息如下: array(10) { ["appid"]=> string(18) "隐藏" ["device_info"]=> string(4) "1000" ["err_code"]=> string(11) "PARAM_ERROR" ["err_code_des"]=> string(26) "JSAPI支付必须传openid" ["mch_id"]=> ...
  • 微信网页JSAPI支付

    2021-02-02 20:52:11
    微信jspi支付只适用于微信内部浏览器使用 JSAPI支付官方文档 主要流程分以下一个步骤 1.根据官方文档的(开发步骤)进行一些相应的配置(域名) 2.进入支付界面后立即执行以下代码 window.location.href = '...
  • 微信支付服务商jsapi支付demo.zip
  • 先了解一下支付操作的大致流程: 微信支付 接入操作步骤 1。环境配置准备 1.1 微信公众号平台 开通微信支付功能 1.2 配置公众号对应产品的访问地址(一级域名) 并把文件放置服务器的根目录 1.3 微信支付平台 开通...
  • JAVA开发微信支付(JSAPI支付

    千次阅读 2020-06-12 00:26:21
    最近开发完了微信支付功能模块,下面就趁热打铁整理下微信支付(JSAPI支付)相关的知识。 1、JSAPI支付 JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,920
精华内容 3,168
关键字:

jsapi支付