有了微信支付方面的一些前期准备以及理论知识后,我们可以开始打造我们的微信支付平台了。

商户向微信公众号提供企业以及银行账户资料,商户功能审核通过后,可以获得以下账户包括财付通的商户账户,用于公众号支付

appId
公众号身份的唯一标识。
paySignKey
公众号支付请求中用于加密的密钥Key,可验证商户唯一身份,PaySignKey对应于支付场景中的appKey值。
appSecret
除了支付请求需要用到paySignKey,公众平台接口API 的权限获取所需密钥Key,在使用所有公众平台API 时,都需要先用它去换取access_token,然后再进行调用(详情参考文档API 接口部分)。
partnerId
财付通商户身份的标识。
partnerKey
财付通商户权限密钥Key。

其中:appSecret、paySignKey、partnerKey是验证商户唯一性的安全标识,对于appSecret和paySignKey的区别,可以这样认为:appSecret是API使用时的登录密码,会在网络中传播的,而paySignKey是在所有支付相关数据传输时用于加密并进行身份校验的密钥,仅保留在第三方后台和微信后台,不会在网络中传播,而且paySignKey仅用于支付请求。

JS API(网页内)支付接口

根据支付场景的交互细节,来设计商户页面的逻辑

(1)用户打开商户网页选购商品,发起支付,在网页通过javascript调用getBrandWCPayRequest接口,发起微信支付请求,用户进入支付流程。

(2)用户成功支付点击完成按钮后,商户的前端会收到javascript的返回值。商户直接跳转支付成功的静态页面进行展示。

(3)商户后台收到来自微信开放平台的支付成功回调通知,标志该笔订单支付成功。

微信JS API只能在微信内置浏览器中使用,其他浏览器调用无效。js的判断方法为:

<span style="white-space:pre">  </span>if(typeof WeixinJSBridge === 'undefined') {alert('微信支付必须在微信内置浏览器中使用.');return;}

微信提供 getBrandWCPayRequest接口供商户前端网页调用,调用之前微信会鉴定商户支付权限,若商户具有调起支付的权限,则将开始支付流程。接口注意:所以传入参数都是字符串类型!   

getBrandWCPayRequest参数以及返回值定义

参数

名称

必填

格式

说明

appId

公众号id

字符串类型

商户注册具有支付权限的公众号成功后即可获得;

timeStamp

时间戳

字符串类型,32个字节以下

商户生成,从1970年1月1日00:00:00至今的秒数,即当前的时间,且最终需要转换为字符串形式;

nonceStr

随机字符串

字符串类型,32个字节以下

商户生成的随机字符串;

package

订单详情扩展字符串

字符串类型,4096个字节以下

商户将订单信息组成该字符串,具体组成方案参见接口使用说明中package组包帮劣;由商户按照规范拼接后传入;

signType

签名方式

字符串类型,参数取值"SHA1"

按照文档中所示填入,目前仅支持SHA1;

paySign

签名

字符串类型

商户将接口列表中的参数按照指定方式迚行签名,签名方式使用signType中标示的签名方式,具体签名方案参见接口使用说明中签名帮劣;由商户按照规范签名后传入;

返回值是:

err_msg 
get_brand_wcpay_request:ok
支付成功

get_brand_wcpay_request:cancel
支付过程用户取消

get_brand_wcpay_request:fail
支付失败

根据官方文档,将相关的函数和方法做了封装,代码如下:

<?php/*** Description of weixinPayHelper** @author kewin*/class weixinPayHelper {public $appId = "";public $appSecret = "";public $partnerId = "";public $paySignKey = "";public $partnerKey = "";public $token = "";public function __construct($appId, $appSecret, $partnerId, $paySignKey, $partnerKey, $token) {$this->appId = $appId;$this->appSecret = $appSecret;$this->partnerId = $partnerId;$this->paySignKey = $paySignKey;$this->partnerKey = $partnerKey;$this->token = $token;}/*** * @param type $api_url* @return boolean*/public function open_request($api_url, $data) {$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $api_url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);if (!empty($data)) {curl_setopt($ch, CURLOPT_POST, 1);curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));}$ret = curl_exec($ch);$error = curl_errno($ch);curl_close($ch);if ($error) {return false;}return $ret;}/*** 对数组排序* @param type $para 排序前的数组* @return type 排序后的数组*/public function argsort($para) {ksort($para);reset($para);return $para;}/*** 把数组所有元素按照"参数=参数值"的模式用&字符拼接成字符串* @param type $para* @return type*/public function createlinkstring($para) {$args = "";foreach ($para as $key => $val) {$args .= strtolower($key) . "=" . $val . "&";}//去掉最后一个&字符if (strlen($args) > 0) {$args = substr($args, 0, count($args) - 2);}//如果存在转义字符,那么去掉转义if (get_magic_quotes_gpc()) {$args = stripcslashes($args);}return $args;}/*** 除去数组中的空值和签名参数* @param type $para* @return type*/public function parafilter($para) {$para_filter = array();foreach ($para as $key => $val) {if ($key == "sign_method" || $key == "sign" || $val == "") {continue;} else {$para_filter[$key] = $para[$key];}}return $para_filter;}/*** 创建sign* @param type $arr* @return type*/public function create_sign($arr) {$para = $this->parafilter($arr);$_signValue = $this->argsort($para);$signValue_ = $_signValue . "&key=" . $this->partnerKey;$signValue = strtoupper(md5($signValue_));return $signValue;}/*** 创建app_signature* @param type $arr* @return type*/public function create_app_signature($arr) {$_para = $this->parafilter($arr);$para = $this->argsort($_para);$signValue = sha1($this->createlinkstring($para));return $signValue;}/**** 生成jsapi支付请求json */public function create_biz_json($package){if($this->check_cft_parameters($package) == false) {   message("生成package参数缺失!" . "<br>");}$nativeObj["appId"] = $this->appId;$nativeObj["package"] = $package;$nativeObj["timeStamp"] = "".time()."";$nativeObj["nonceStr"] = $this->create_noncestr();$nativeObj["paySign"] = $this->getSign($nativeObj);$nativeObj["signType"] = 'SHA1';return   json_encode($nativeObj);}/*** 获取paySign* @param type $package*/public function getSign($bizObj){foreach ($bizObj as $k => $v){$bizParameters[strtolower($k)] = $v;}$bizParameters["appkey"] = $this -> paySignKey;ksort($bizParameters); $bizString = $this->formatBizQueryParaMap($bizParameters, false);return sha1($bizString);}function check_cft_parameters($package){if($package["bank_type"] == null || $package["body"] == null || $package["partner"] == null || $package["out_trade_no"] == null || $package["total_fee"] == null || $package["fee_type"] == null ||$package["notify_url"] == null || $package["spbill_create_ip"] == null || $package["input_charset"] == null){return false;}return true;}function getToken($weid) {$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";$content = ihttp_get($url);if (empty($content) || !is_array($content)) {message('获取微信公众号授权失败, 请稍后重试!');}$token = @json_decode($content['content'], true);if (empty($token) || !is_array($token)) {message('获取微信公众号授权失败, 请稍后重试! 公众平台返回原始数据为: <br />' . $content['meta']);}if (empty($token['access_token']) || empty($token['expires_in'])) {message('解析微信公众号授权失败, 请稍后重试!');}$record = array();$record['token'] = $token['access_token'];$record['expire'] = TIMESTAMP + $token['expires_in'];$row = array();$row['access_token'] = iserializer($record);pdo_update('wechats', $row, array('weid' => $weid));return $record['token'];}/*** 发货通知* @param type $openid* @param type $transid 交易单号* @param type $out_trade_no 商户订单号* @param type $deliver_status* @param type $deliver_msg* @return type*/public function delivernotify($weid,$openid, $transid, $out_trade_no, $deliver_status = '1', $deliver_msg = 'ok') {$post = array();$post['appid'] = $this->appId;$post['appkey'] = $this->paySignKey;$post['openid'] = $openid;$post['transid'] = $transid;$post['out_trade_no'] = $out_trade_no;$post['deliver_timestamp'] = time();$post['deliver_status'] = $deliver_status;$post['deliver_msg'] = $deliver_msg;ksort($post);$bizString = $this -> formatBizQueryParaMap($post, false);$post['app_signature']  = sha1($bizString);$post['sign_method'] = "SHA1";$jsonmenu = '{"appid" : "'.$post['appid'].'","openid" : "'.$post['openid'].'","transid" : "'. $post['transid'].'","out_trade_no" : "'.$post['out_trade_no'].'","deliver_timestamp" : "'.$post['deliver_timestamp'].'","deliver_status" : $deliver_status,"deliver_msg" : $deliver_msg,"app_signature" : "'.$post['app_signature'].'","sign_method" : "sha1"}';$url = "https://api.weixin.qq.com/pay/delivernotify?access_token=".$this->token;$ret = $this->open_request($url, $jsonmenu);if ( in_array($ret['errcode'],array(40001,40002,42001))){$this->token = $this->getToken($weid);return $this->delivernotify($weid,$openid,$transid,$out_trade_no,$deliver_status,$deliver_msg);}return $ret;}/*** 订单查询* @param type $out_trade_no* @return type*/public function order_query($out_trade_no) {$post = array();$post['appid'] = $this->appId;$sign = $this->create_sign(array('out_trade_no' => $out_trade_no, 'partner' => $this->partnerId));$post['package'] = "out_trade_no=$out_trade_no&partner=" . $this->partnerId . "&sign=$sign";$post['timestamp'] = time();$post['app_signature'] = $this->create_app_signature(array('appid' => $this->appId, 'appkey' => $this->paySignKey, 'package' => $post['package'], 'timestamp' => $post['timestamp']));$post['sign_method'] = "SHA1";$data = json_encode($post);$url = 'https://api.weixin.qq.com/pay/orderquery?access_token=' . $this->token;$ret = $this->open_request($url, $data);return $ret;}/*** 构建支付请求数组* @param type $parameter* @return type*/public function buildForm($parameter) {$parameter['package'] = $this->buildPackage($parameter); //生成订单package$paySignArray = array('appid' => $this->appId, 'appkey' => $this->paySignKey, 'noncestr' => $parameter['noncestr'], 'package' => $parameter['package'], 'timestamp' => $parameter['timestamp']);$parameter['paysign'] = $this->create_app_signature($paySignArray);return $parameter;}function formatBizQueryParaMap($paraMap, $urlencode){$buff = "";ksort($paraMap);foreach ($paraMap as $k => $v){if($urlencode){$v = urlencode($v);}$buff .= strtolower($k) . "=" . $v . "&";}$reqPar;if (strlen($buff) > 0) {$reqPar = substr($buff, 0, strlen($buff)-1);}return $reqPar;}function formatQueryParaMap($paraMap, $urlencode){$buff = "";ksort($paraMap);foreach ($paraMap as $k => $v) {if (null != $v && "null" != $v && "sign" != $k) {if ($urlencode) {$v = urlencode($v);}$buff .= $k . "=" . $v . "&";}}$reqPar;if (strlen($buff) > 0) {$reqPar = substr($buff, 0, strlen($buff) - 1);}return $reqPar;}/*** 构建支付请求包* @param type $parameter* @return type*/public function buildPackage($parameter) {$filter = array('bank_type', 'body', 'attach', 'partner', 'out_trade_no', 'total_fee', 'fee_type', 'notify_url', 'spbill_create_ip', 'time_start', 'time_expire', 'transport_fee', 'product_fee', 'goods_tag', 'input_charset');$base = array('bank_type' => 'WX','fee_type' => '1','input_charset' => 'UTF-8','partner' => $this->partnerId,'noncestr' => md5(uniqid(time(), true)));$parameter = array_merge($parameter, $base);$unSignParaString = $this->formatQueryParaMap($parameter, false);$paraString = $this->formatQueryParaMap($parameter, true);     $string = $unSignParaString."&key=" . $this->partnerKey;$sign = strtoupper(md5($string));return $paraString . "&sign=" . $sign;}/*** 从xml中获取数组 post过来的数据* @return boolean*/public function getXmlArray() {$postStr = file_get_contents('php://input');if ($postStr) {$postStr = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);if (!is_object($postStr)) {return false;}$array = json_decode(json_encode($postStr), true); //xml对象转数组return array_change_key_case($array, CASE_LOWER); //所有键小写} else {return false;}}/*** 创建随机串* @param type $length* @return type*/public function create_noncestr($length = 16) {$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";$str = "";for ($i = 0; $i < $length; $i++) {$str.= substr($chars, mt_rand(0, strlen($chars) - 1), 1);}return $str;}public function trimString($value) {$ret = null;if (null != $value) {$ret = $value;if (strlen($ret) == 0) {$ret = null;}}return $ret;}}

有了工具类后,就可以开始我们的支付流程过程需要的函数调用了, 附上一个微信支付的demo——pay.php

<?php
/*** [WeEngine System] Copyright (c) 2013 WE7.CC* kewin*/
require '/www/web/weixin.shike001.com/source/bootstrap.inc.php';
include '../../source/class/weixinPayHelper.class.php';
取得公众号的一下数据$appid $secret $partnerId $paySignKey $partnerKey $token $weixin = new weixinPayHelper($appid, $secret, $partnerId, $paySignKey, $partnerKey, $token);$body = $_GET['title'];
$fee = $_GET['fee']*100;
$create_ip = $_W['clientip'];$data = array('body' => $body,'spbill_create_ip' => $create_ip,'total_fee' => "$fee",'attach' => '120','notify_url' => $_W['siteroot'] . 'notify2.php','out_trade_no' => $weixin->create_noncestr(),
);$package = $weixin->buildPackage($data);?><!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<title>微信支付</title>
<script type='text/javascript' src='../../resource/script/jquery-1.7.2.min.js'></script>
<style>.pay_table{border:1px solid #cad9ea;border-collapse: collapse;width:100%;font-size:15px;}.pay_table th{height:35px;background:#003399;color:#ffffff;font-size:16px;}.pay_table td{border:1px solid #aaa;height:30px;}</style>
<script language="javascript">
function callpay()
{if(typeof WeixinJSBridge === 'undefined') {alert('微信支付必须在微信内置浏览器中使用.');return;}WeixinJSBridge.invoke('getBrandWCPayRequest',<?php echo $weixin->create_biz_json($package);?>,function(res){WeixinJSBridge.log(res.err_msg);if(res.err_msg == "get_brand_wcpay_request:ok"){//支付成功后的跳转
<span style="white-space:pre">      </span>window.location.href="";}else{//返回跳转到订单详情页面window.location.href="";}});
}
</script>
<body>
<div style=""><table class="pay_table"><th>订单支付</th><tr><td>订单名称:<?php echo $_GET['title']?></td></tr><tr><td>支付金额:<?php echo sprintf('%.2f', $_GET['fee']);?><span class="muted"> 元</span></td></tr></table><button type="button" style="width:100%;height:40px" οnclick="callpay()">微信支付</button>
</div></body>
</html>

但此时要注意一个问题,微信的授权目录和请求路径已经固定,所以pay.php需要是请求调用的而不能是直接包含进某个功能块的,在这里我们可以跳转到支付页面,连接后面跟上需要的参数

至此,可以实现付款了。

微信支付——开发体系相关推荐

  1. java微信支付必要参数_微信支付 开发账号体系各参数详解

    商户在微信公众平台提交申请资料以及银行账户资料,资料审核通过并签约后,可以获得表6-4所示帐户(包含财付通的相关支付资金账户),用于公众帐号支付. 帐号及作用: appid :公众帐号身份的唯一标识. ...

  2. 微信支付开发(2) 微信支付账号体系

    本文介绍微信支付账号体系各参数. 商户在微信公众平台提交申请资料以及银行账户资料,资料审核通过并签约后,可以获得表6-4所示帐户(包含财付通的相关支付资金账户),用于公众帐号支付. 帐号 作用 app ...

  3. 微信服务号 微信支付开发

    微信支付,须要通过微信支付验证 眼下.支付仅限服务号, 做微信支付开发,主要看开发文档 统一下单. 订单查询 退款等 1.发起支付.都是通过h5发起的,首先获取prepay_id 发起支付,须要统一下 ...

  4. 微信支付通知 php,微信支付开发交易通知实例

    一.交易通知 用户在成功完成支付后,微信后台通知(POST)商户服务器(notify_url)支付结果.商户可以使用notify_url的通知结果进行个性化页面的展示. 对后台通知交互时,如果微信收到 ...

  5. 微信支付 php编程,PHP编程:微信支付开发交易通知实例

    <PHP编程:微信支付开发交易通知实例>要点: 本文介绍了PHP编程:微信支付开发交易通知实例,希望对您有用.如果有疑问,可以联系我们. 一.交易通知 用户在成功完成支付后,微信后台通知( ...

  6. 微信支付开发(6) 收货地址共享接口

    关键字:微信支付 收货地址共享 作者:方倍工作室 原文: http://www.cnblogs.com/txw1958/p/weixin-editAddress.html 请看新版教程  微信支付开发 ...

  7. 微信支付开发准备工作和详细步骤

    微信支付前的准备工作 1 开发者资质认证 微信支付开发第一步就是使用公司管理者/高层帐号登录微信开放平台,进入"账号中心",进行开发者资质认证,需要填写公司资料,包括但不限于,公司 ...

  8. 工作笔记——微信支付开发相关知识整理

    在最近的工作中,引入了微信小程序支付,在开发过程中积累和整理了一些技术知识,现将其整理如下 目录 一.概念认识 (一)术语介绍 (二)名词解释 (四)对接微信支付接口规则整理 二.微信支付开发参考 ( ...

  9. JSAPI微信支付开发流程和坑

    首先,我先简要说明一下微信支付开发的流程 众所周知,工欲善其事,必先利其器,微信官方推出了web微信开发工具,有windows.linux.版本的,根据自己的开发环境选择合适自己的,登陆公众平台--& ...

最新文章

  1. Samba服务器配置(1)--源码安装
  2. 3.6.1 局域网的基本概念和体系结构
  3. 加密算法 AES MD5 SHA1
  4. 华人“军火专家”——黄仁勋 1
  5. SqlServer为字段创建索引
  6. 一、HTML和CSS基础--HTML+CSS基础课程--第1部分
  7. (227)FPGA学习基础
  8. 如何让Ubuntu 14重启后,保存屏幕亮度的设置
  9. 车道线检测-python实现
  10. lopatkin俄大神最新精简中文系统Windows 7 Professional VL SP1 7601.24496 x86-x64 ZH-CN DREY
  11. 在浏览器用域名访问发现跳转到IIS Windows 界面
  12. vue导出excel乱码(锟斤拷唷?锟?;锟斤拷)
  13. 电子工作室培训(一)单片机环境搭建,keil5 新建工程及流水灯
  14. Django项目处女作
  15. EXCEL-如何把多个格式相同的表格批量做成图表
  16. python生僻字如何转码_装13失败后,我决定使用Python为生僻字批量注音
  17. 用python做一个自动签到程序
  18. 2022Java春招面试,java工程师面试宝典
  19. 获得当前时间的格林威治时间毫秒数
  20. S905盒子应该使用的dtb包

热门文章

  1. 超级搞笑~`记得转噢
  2. 计算机关机速度,加快win7关机速度如何操作【图解】
  3. vue-devtools安装文件 (百度下载网盘下载)
  4. father's短信
  5. 基于深度学习的可解释特征准确预测混凝土抗压强度
  6. Unity Shader学习三:坐标空间的变换
  7. HitFilm Pro中文版
  8. 【SQL注入14】布尔盲注的半自动化实现(基于BurpSuite工具和sqli-labs-less8靶机平台)
  9. 解决SpringCloud之Feign超时问题(Read timed out executing POST http://***)
  10. WebService客户端设计期TClientDataSet.ProviderName无值解决