微信支付有多种支付场景,有扫码支付、公众号支付、H5 支付、APP 应用支付等。
之前有写过一篇关于扫码支付的文章,今天,写一下关于公众号支付(jsapi支付)的一些知识。
我们在微信支付平台下载开发文档,其中,刷卡支付、公众号支付、扫码支付是统一放在一个压缩包里,压缩包为:WxpayAPI_php_v3。
将压缩包解压后,打开目录 example,其中,有二个文件是需要我们写业务代码的,一个jsapi.php 文件,这个文件主要用于获取用户的 openid 和传入支付的订单信息;
另一个文件是 notify.php,这个文件是支付成功后的回调文件,我们需要在这个文件里,写入支付成功后的业务逻辑,如更新订单状态为“已支付”。
一定要在支付平台设置支付授权目录,授权目录为要访问的文件所在目录,如:www.域名.com/zhifu/example/
实际操作:
1、当用户到达支付页面后,我们可以让用户点击支付按钮,当点击这个支付按钮后,我们将 order_id 这个参数传入到 jsapi.php 文件,在 jsapi.php 文件中,我们接收传入的 order_id ,重新查询订单信息。
2、我们将订单信息的关键内容,如需要支付的金额,产品的名称,放入到微信的参数中。
3、点击底部的支付按钮,唤醒微信的支付功能。
4、支付成功后,微信会访问到之前配置的回调地址文件。
jsapi.php 文件代码:
ini_set('date.timezone','Asia/Shanghai');
//error_reporting(E_ERROR);
require_once "../lib/WxPay.Api.php";
require_once "WxPay.JsApiPay.php";
require_once 'log.php';
//连接数据库
$servername = "localhost";
$username = "****";
$password = "****";
if (!$link = mysql_connect($servername, $username, $password)) {
echo 'Could not connect to mysql';
exit;
}
if (!mysql_select_db('****', $link)) {
echo 'Could not select database';
exit;
}
//根据传入的 order_id 获取订单信息
$order_id = $_GET['order_id'];
$sql = "SELECT * FROM v9_chongzhi_order where id={$order_id} ";
$result = mysql_query($sql, $link);
$order_info = mysql_fetch_assoc($result);
if($order_info['is_pay']==1){//如果订单已经支付,则直接跳走
header("Location:/index.php?m=member&c=index&from=mobile");
}
//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);
//打印输出数组信息
function printf_info($data)
{
foreach($data as $key=>$value){
echo "$key : $value
";
}
}
//①、获取用户openid
$tools = new JsApiPay();
$openId = $tools->GetOpenid();
//②、统一下单
$input = new WxPayUnifiedOrder();
$input->SetBody("充值");//这里传入的是商品信息
$input->SetAttach("chongzhi");
$input->SetOut_trade_no($order_info['sn']);//这里传入的是订单号
$input->SetTotal_fee($order_info['chongzhi_money']);//这里传入的是需要支付的金额
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("chongzhi");
$input->SetNotify_url("http://www.域名.com/zhifu/weixin/example/gongzhonghao_notify.php");
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openId);
$order = WxPayApi::unifiedOrder($input);
echo '下单支付单信息
';
//printf_info($order_info);
echo "订单号 : {$order_info['sn']}
";
echo "充值金额 : ".($order_info['chongzhi_money']/100)." 元
";
$jsApiParameters = $tools->GetJsApiParameters($order);
//获取共享收货地址js函数参数
$editAddress = $tools->GetEditAddressParameters();
//③、在支持成功回调通知中处理成功之后的事宜,见 notify.php
/**
* 注意:
* 1、当你的回调地址不可访问的时候,回调通知会失败,可以通过查询订单来确认支付是否成功
* 2、jsapi支付时需要填入用户openid,WxPay.JsApiPay.php中有获取openid流程 (文档可以参考微信公众平台“网页授权接口”,
* 参考http://mp./wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html)
*/
?>
微信支付样例-支付
//调用微信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();
}
}
//获取共享地址
function editAddress()
{
WeixinJSBridge.invoke(
'editAddress',
<?php echo $editAddress; ?>,
function(res){
var value1 = res.proviceFirstStageName;
var value2 = res.addressCitySecondStageName;
var value3 = res.addressCountiesThirdStageName;
var value4 = res.addressDetailInfo;
var tel = res.telNumber;
//alert(value1 + value2 + value3 + value4 + ":" + tel);
}
);
}
window.onload = function(){
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', editAddress, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', editAddress);
document.attachEvent('onWeixinJSBridgeReady', editAddress);
}
}else{
editAddress();
}
};
该笔订单支付金额为<?php echo $order_info['chongzhi_money']/100; ?>元
<?php if($order_info['is_pay']==0){?>立即支付<?php } ?>
返回个人中心
notify.php 文件代码:
ini_set('date.timezone','Asia/Shanghai');
error_reporting(E_ERROR);
require_once "../lib/WxPay.Api.php";
require_once '../lib/WxPay.Notify.php';
require_once 'log.php';
//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);
class PayNotifyCallBack extends WxPayNotify
{
//查询订单
public function Queryorder($transaction_id)
{
$input = new WxPayOrderQuery();
$input->SetTransaction_id($transaction_id);
$result = WxPayApi::orderQuery($input);
Log::DEBUG("query:" . json_encode($result));
if(array_key_exists("return_code", $result)
&& array_key_exists("result_code", $result)
&& $result["return_code"] == "SUCCESS"
&& $result["result_code"] == "SUCCESS")
{
//在这里写关于支付后的业务逻辑,如更新订单状态
$servername = "localhost";
$username = "******";
$password = "******";
if (!$link = mysql_connect($servername, $username, $password)) {
echo 'Could not connect to mysql';
exit;
}
if (!mysql_select_db('*****', $link)) {
echo 'Could not select database';
exit;
}
$order_sn = $result['out_trade_no'];
$update_order_sql = "update chongzhi_order set pay_time={$result['time_end']},pay_amount={$result['total_fee']},is_pay=1 where sn='{$order_sn}' ";//echo $sql;
$update_order_result = mysql_query($update_order_sql, $link);
$order_sql = "SELECT * FROM chongzhi_order where sn='{$order_sn}' ";//echo $sql;
$order_result = mysql_query($order_sql, $link);
$order_info = mysql_fetch_assoc($order_result);
$chongzhi_money = round($result['total_fee']/100,2);
$update_amount_sql = "update member set amount=amount+{$chongzhi_money} where userid={$order_info['user_id']} ";//echo $sql;
$update_amount_result = mysql_query($update_amount_sql, $link);
return true;
}
return false;
}
//重写回调处理函数
public function NotifyProcess($data, &$msg)
{
Log::DEBUG("call back:" . json_encode($data));
$notfiyOutput = array();
if(!array_key_exists("transaction_id", $data)){
$msg = "输入参数不正确";
return false;
}
//查询订单,判断订单真实性
if(!$this->Queryorder($data["transaction_id"])){
$msg = "订单查询失败";
return false;
}
return true;
}
}
Log::DEBUG("begin notify");
$notify = new PayNotifyCallBack();
$notify->Handle(false);
结尾再次提醒:一定要在支付平台设置支付授权目录,授权目录为要访问的文件所在目录,如:www.域名.com/zhifu/example/