php 微信公众号支付

微信公众号支付用于用户在微信内使用自己的网页进行支付

一、一般的流程为:

    (1)、商户下发图文消息或者通过自定义菜单吸引用户点击进入商户网页。

    (2)、进入商户网页,用户选择购买,完成选购流程。

    (3)、调起微信支付控件,用户开始输入支付密码。

    (4)、密码验证通过,支付成功。商户后台得到支付成功的通知。

    (5)、返回商户页面,显示购买成功。该页面由商户自定义。

    (6)、微信支付公众号下发支付凭证。

    (7)、商户公众号下发消息,提示发货成功。该步骤可选。或是商户app/网站发送消息 提示购买成功。

二、交互细节:
    以下是支付场景的交互细节,请认真阅读,设计商户页面的逻辑:
    (1)用户打开商户网页选购商品,发起支付,在网页通过JavaScript调用getBrandWCPayRequest接口,发起微信支付请求,用户进入支付流程。
    (2)用户成功支付点击完成按钮后,商户的前端会收到JavaScript的返回值。商户可直接跳转到支付成功的静态页面进行展示。
    (3)商户后台收到来自微信开放平台的支付成功回调通知,标志该笔订单支付成功。

注:(2)和(3)的触发不保证遵循严格的时序。JS API返回值作为触发商户网页跳转的标志,但商户后台应该只在收到微信后台的支付成功回调通知后,才做真正的支付成功的处理。

三、开发配置

    (1)设置支付目录

        请确保实际支付时的请求目录与后台配置的目录一致,否则将无法成功唤起微信支付。

        在微信商户平台(pay.weixin.qq.com)设置您的公众号支付支付目录,设置路径:商户平台-->产品中心-->开发配置。

        公众号支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

    (2)设置授权域名

        开发公众号支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。

php 微信公众号支付

四、微信内H5调起支付

    getBrandWCPayRequest参数以及返回值定义:
    php 微信公众号支付

get_brand_wcpay_request:ok 支付成功
get_brand_wcpay_request:cancel 支付过程中用户取消
get_brand_wcpay_request:fail 支付失败

调用支付JSAPI缺少参数:total_fee 请检查预支付会话标识prepay_id是否已失效


js 的代码如下

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();

}


php的代码如下

<?php 
require_once "../lib/WxPay.Api.php";
require_once "WxPay.JsApiPay.php";
//①、获取用户openid
$tools = new JsApiPay();
$openId = $tools->GetOpenid();


//②、统一下单
$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); 

注意要将 jsApiParameters  参数返回代上个js的getBrandWCPayRequest 中

?>


其中 PHP方面要注意的是 

1、获取用户公众号的openid  会调用这个方法两次

2、公众号支付配置 appid 一定是公众号的appid

/**

* 通过跳转获取用户的openid,跳转流程如下:
* 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
* 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code

* @return 用户的openid
*/
public function GetOpenid()
{
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
$url = $this->__CreateOauthUrlForCode($baseUrl);
Header("Location: $url");
exit();
} else {
//获取code码,以获取openid
    $code = $_GET['code'];
$openid = $this->getOpenidFromMp($code);
return $openid;
}
}