1、开发前准备
开发前,需要准备好以下资料:微信公众号AppId,商户号mchid,密钥key,微信公众号APPSecret,API证书
(1)申请微信认证服务号,开通微信支付,并在微信支付后台,关联服务号的appid
(2)下载微信支付sdk:https://pay./wiki/doc/api/jsapi.php?chapter=11_1
(3)准备支付接入的域名,为域名申请SSL证书,配置服务器,具体方法如下:如何配置SSL,并让http转向https_开心lulu的博客-CSDN博客_http配置ssl
(3)设置JSAPI支付授权目录,操作步骤:登录微信支付商户平台(https://pay.) >> 产品中心 >> 开发配置 >>支付配置 >> 支付授权目录,如下图:
(4)设置APIv2密钥,操作步骤:登录微信支付商户平台(https://pay.)>> 账户中心 >> 账户设置 >> API安全 >> APIv2密钥 >> 设置
(5)申请API证书,操作步骤:登录微信支付商户平台(https://pay.)>> 账户中心 >> 账户设置 >> API安全 >> 申请API证书 >> 管理证书
步骤参照:/faq/161222NneAJf161222U7fARv.html
点击下载证书工具;下载后,双击“WXCertUtil.exe”文件,选择安装路径后,点击申请证书
也可通过以下链接下载证书工具:
windows版本:/mch/files/WXCertUtil.exe
mac版本:/mch/files/WXCertUtil.dmg
在【证书工具】,填写商户号信息(商户号、商户名称),点击下一步
在【证书工具】,复制证书请求串
(若提示"请粘贴请求串到商户平台获取证书串",请在第5点步骤检查是否已粘贴。可同时尝试手动鼠标复制粘贴的方法)
在【商户平台】,粘贴证书请求串
在【商户平台】,输入操作密码,安全验证后生成证书串
在【商户平台】,复制证书串
在【证书工具】,粘贴证书串,点击下一步,申请证书成功
(若提示"证书与本地公私钥不匹配",可能是浏览器禁用了剪切板复制功能。请在操作步骤第7点,操作时使用鼠标选中全部证书串内容(注意右边有下拉框),单击鼠标右键选择复制)
提醒:请将生成的证书文件转交给技术人员,由技术人员将证书部署到服务器上(请务必妥善保管证书及私钥,因为私钥文件只能通过证书工具导出,若私钥丢失,则无法找回,只能作废后重新申请。)
(6)获取APPSecret
2、部署sdk包
将第一步下载下来的sdk包改名为 WxpayJSAPI(可自由命名),复制到ThinkPHP\Library\Vendor目录下,以便后续调用。
原包中没有cert和logs目录,新建cert用来存放证书,当然,你也可以存放在你喜欢的目录,之后在配置文件中修改证书目录即可,logs日志目录同理。
3、修改包中的引用路径
即将所有的 require_once “…/” 改成 VENDOR_PATH 路径
如果觉得修改麻烦,可以直接下载我修改好的:/download/zhouyankaixin/86540539
4、修改配置文件
打开文件 WxPayJsapi/example/WxPay.Config.php
修改里面的配置信息
5、编写支付的控制器和视图
我创建的控制器为:WxPayController.class.php,方法为:payJsApi,代码如下:
public function payJsApi(){//订单ID$id=I('id',0,'intval');/*这里可以获取订单相关信息,做对应判断*///引入文件vendor('WxPayJsapi.example.WxPay#JsApiPay');try{$tools = new \JsApiPay();$openId = $tools->GetOpenid();//②、统一下单$input = new \WxPayUnifiedOrder();$input->SetBody('商品名称');$input->SetAttach("test");$input->SetOut_trade_no("订单编号");$input->SetTotal_fee("1");//订单金额,单位分$input->SetTime_start(date("YmdHis"));//微信支付订单过期时间,以下表示过期时间为10分钟$input->SetTime_expire(date("YmdHis", time() + 600));$input->SetGoods_tag("商品标签");//完整回调页面:https://...$input->SetNotify_url("回调页面");$input->SetTrade_type("JSAPI");$input->SetOpenid($openId);$config = new \WxPayConfig();$order = \WxPayApi::unifiedOrder($config, $input);$jsApiParameters = $tools->GetJsApiParameters($order);//下单成功后,需要将微信返回的接口json字符串保存到数据库中,以便用户暂时未支付时,下次点开可支付/*保存代码*/$this->assign('jsApiParameters',$jsApiParameters);//获取共享收货地址js函数参数(如果不需要收货地址,这里可以删除)$editAddress = $tools->GetEditAddressParameters();$this->display();exit;} catch(Exception $e) {\Log::ERROR(json_encode($e));}}
视图代码如下(以下不需要收货地址),如有需要修改收货地址,可参考官方DEMO:WxPayJsapi/example/jsapi.php
<script type="text/javascript">var jsApiParameters={$jsApiParameters};function jsApiCall(){WeixinJSBridge.invoke('getBrandWCPayRequest',jsApiParameters,function(res){if(res.err_msg=='get_brand_wcpay_request:ok'){//支付成功//...}else{if(res.err_msg=='get_brand_wcpay_request:cancel'){//取消alert('支付已取消');}else{//支付失败alert(res.err_code+res.err_desc+res.err_msg);}}});}function callpay(){jsApiCall();}</script><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>
访问支付页面:
6、回调
public function notifyWx(){//回调数据,xml格式$strXml=$GLOBALS['HTTP_RAW_POST_DATA'];//将xml转成数组$reData=xmlToArray($strXml);if($reData['return_code']=='SUCCESS'){//订单ID$transaction_id=$reData['transaction_id'];//查询订单状态vendor('WxPayJsapi.example.notify');//引入文件$notify=new \PayNotifyCallBack();$result=$notify->Queryorder($transaction_id);if(!$result){//支付失败的echo '该订单还没支付';exit;}/*修改订单状态,保存支付记录*/}exit;}
/*** xml转数组* @param string $xmlStr xml字符串*/function xmlToArray($xmlStr){//1.xml数据转成object对象$xml = simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);//2.object对象转json格式$xml = json_encode($xml);//3.json格式转数组$arr = json_decode($xml,true);return $arr;}