前期:JSAPI微支付的开发-准备工作
集成:JSAPI微支付的开发-开发阶段
上线:JSAPI微支付的开发-正式上线
看到这篇文章前你应该完了通过了微支付申请,商户平台API证书(下载下来) 和API密钥(在商户平台设置好)也设置好了才对。否则请参考准备工作:JSAPI微支付的开发-准备工作
微支付开发必须得在线上,因为涉及到oauth等网页授权跳转,搭建好开发服务器后先正确的配置测试目录和测试帐号:
微支付-开发配置
想必大家都是用的框架吧,框架的话测试目录填写到你的控制器就好,如果没用框架就填写到你的脚本文件。
测试白名单:在没有正式发布前只有测试白名单的微信号能发起正常的支付请求,别忘了把自己的帐号输进去。
接下来去微信公众平台-微信支付-支付申请的说明部分有 公众号微信支付申请指引 这里面有demo包的下载地址,拉到最下面就能看到 微信支付接口文档及开发工具 下载第三个 微信支付接口文档及demo(公众账号).zip点击下载 即可
下载好解压:
文档结构
PHP版本
|-- README.txt---------------------使用说明文本
|-- WxPayHelper--------------------微信支付类库及配置文件
| |-- SDKRuntimeException.php----异常处理类
| |-- WxPay.pub.config.php-----------商户配置文件
| |-- WxPayPubHelper.php------------微信支付类库
| |--cart----------------------------存放证书的文件夹
|-- demo---------------------------例程
| |-- js_api_call.php------------JSAPI支付例程
| |-- native_call_qrcode.php-----native支付静态链接二维码例程
| |-- native_call.php------------native支付后台响应例程
| |-- native_call.log------------native支付后台响应日志
| |-- native_dynamic_qrcode.php--native支付动态链接二维码例程
| |-- notify_url.php-------------支付结果异步通知例程
| |-- notify_url.log-------------支付结果异步通知日志
| |-- order_query.php------------订单查询例程
| |-- refund.php-----------------退款例程
| |-- download_bill.php----------对账单例程
| |-- refund_query.php-----------退款查询例程
| |-- log_.php-------------------日志类
| |-- qrcode.js------------------二维码生成工具
|-- index.php
这里我们只讲解最基本的完整的支付流程
需要配置的参数项都在WxPayHelper->WxPay.pub.config.php中
const APPID = 'wx8888888888888888';//公众号开发者中心,肯定都知道
const MCHID = '1888888789';//收到审核通过的邮件时里面的微信支付商户号,现在是10位,之前是8位吧
const KEY = '48888888888888888888888888888886';//商户支付密钥,即我们上一篇中所拿到的API密钥
const APPSECRET = '48888888888888888888888888888887';//公众号开发者中心,肯定都知道
//这个主要是支付界面里判断是否获取到code的机制,若没获取到则会跳转授权页面进行获取,code是我们获取 access_token和openid的必要参数,当然,这里的access_token是说oauth授权中的访问令牌,是用来获取用户 信息的,并不是我们平时调用其他微信接口时必须的那个access_token
const JS_API_CALL_URL = 'http://www.xxxxxx.com/demo/js_api_call.php';
//证书路径,注意应该填写绝对路径,即从你的服务器根目录开始写,注意不能跨域,证书上一篇中我们也讲了怎 么到手
const SSLCERT_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_cert.pem';
const SSLKEY_PATH = '/xxx/xxx/xxxx/WxPayPubHelper/cacert/apiclient_key.pem';
//异步通知url,支付完成后微信服务器会异步推送支付结果,可以做更丰富的开发
const NOTIFY_URL = 'http://www.xxxxxx.com/demo/notify_url.php';
//本例程通过curl使用HTTP POST方法,此处可修改其超时时间,默认为30秒
const CURL_TIMEOUT = 30;
支付请求的功能主要是在js_api_call.php中实现的
支付请求的步骤为:
1、通过oauth授权获取code,用code获取access_token,用access_token获取openid,想必大家都很了解啦
<?php //=========步骤1:网页授权获取用户openid============ //通过code获得openid if (!isset($_GET['code'])) { //触发微信返回code码 $url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL); Header("Location: $url"); }else { //获取code码,以获取openid $code = $_GET['code']; $jsApi->setCode($code); $openid = $jsApi->getOpenId(); }
2、设置统一支付接口参数,订单号,交易描述,交易金额(注意交易金额以分为单位),并获取prepay_id
//=========步骤2:使用统一支付接口,获取prepay_id============ //使用统一支付接口 $unifiedOrder = new UnifiedOrder_pub(); //设置统一支付接口参数 //设置必填参数 //appid已填,商户无需重复填写 //mch_id已填,商户无需重复填写 //noncestr已填,商户无需重复填写 //spbill_create_ip已填,商户无需重复填写 //sign已填,商户无需重复填写 $unifiedOrder->setParameter("openid","$openid");//openid $unifiedOrder->setParameter("body","贡献一分钱");//商品描述 $out_trade_no = date('YmdHis').time();//自定义订单号,此处仅作举例 $unifiedOrder->setParameter("out_trade_no","$out_trade_no"); $unifiedOrder->setParameter("total_fee","1");//总金额,注意是以分为单位 $unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址 $unifiedOrder->setParameter("trade_type","JSAPI");//交易类型 //非必填参数,可根据实际情况选填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号 //$unifiedOrder->setParameter("device_info","XXXX");//设备号 //$unifiedOrder->setParameter("attach","XXXX");//附加数据 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间 //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记 //$unifiedOrder->setParameter("openid","XXXX");//用户标识 //$unifiedOrder->setParameter("product_id","XXXX");//商品ID //获取prepay_id $prepay_id = $unifiedOrder->getPrepayId();
3、获取支付请求数据包,此时的$jsApiParameters已经是一个完整的支付数据包了,将填充到jsApiCall函数中,其实并不是你点支付才去生成数据包,而是你进入支付界面前他就已经生成了必要的参数包,大家做MVC化时注意这点。
$jsApiParameters = $jsApi->getParameters();
4、调用js发起支付请求,jsApiCall里已经填充好了jsApiParameters,官方demo里并没有给出支付结果返回状态的处理,这里我们详细给出
function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', <?php echo $jsApiParameters;?>, function(res){ WeixinJSBridge.log(res.err_msg); switch (res.err_msg) { //支付成功 case 'get_brand_wcpay_request:ok': break; //支付取消 case 'get_brand_wcpay_request:cancel': break; //支付失败 case 'get_brand_wcpay_request:fail': break; default: break; } }); } function callpay() { if (typeof WeixinJSBridge == "undefined") { //添加监听事件,兼容写法,ms需要用attacheEvent if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } } else { //调用js请求 jsApiCall(); } }
至于其他的功能我们就不在叙述了,为了提高用户体验你还可以加入收货地址共享组件,获取用户的收货地址自动填写,支付成功异步通知的功能等。
网页授权获取code
code获取access_token
access_token获取openid
用openid联合预先设置好的相关参数组包获取prepay_id
最终组包成支付请求数据包,传递给jsApiCall函数里的数据位,等待页面调用
jsApiCall会获此次支付的返回状态,ok陈功,cancel取消,failed失败,根据对应的状态进行相关处理即可
友情提示:微信缓存较大,且必须在微信场景下做调试,只能一点点的alert数据好了,按步骤一步步的来,认真配置每一项参数,不会有很大问题。
相关问题:
1、package中的参数partner或prepay_id为空
此问题较为普遍,据本人经验并不是哪里的参数错填漏填了,而是...你用的开发包有问题....微支付php demo有几版是有问题的,没办法获取prepay_id,你可以先试着更换成官方最新的demo包,文章里我提供的就是可以的,如果还不行那再检查下参数是不是错填漏填了,复制有没有多个空格什么的。
2、微支付V3版MVC化的简述
发起支付请求1、2两部可放在C中,即获取openid和组装支付请求包,js部分放在V中,将C中组装的数据包传递给V中的jsApiCall即可,其他预配置项放在你的项目配置参数设置中即可。