easywechat 配置

 public function __construct(){$configModel = new Setting();$this->orderModel = new Orders();$this->memberModel = new Members();$config = [// 必要配置'app_id' => $configModel->get('ADMIN_APP_ID')->conf_value,'secret' => $configModel->get('ADMIN_SECRET')->conf_value,'mch_id' => $configModel->get('ADMIN_MCH_ID')->conf_value,'key' => $configModel->get('ADMIN_KEY')->conf_value,   // API 密钥// 如需使用敏感接口(如退款、发送红包等)需要配置 API'cert_path' => $configModel->get('ADMIN_CERT_PATH')->conf_value, // XXX: 绝对路径!!!!'key_path' => $configModel->get('ADMIN_KEY_PATH')->conf_value,    // XXX: 绝对路径!!!!'notify_url' => '',     // 可以在下单时单独设置覆盖它'log' => ['level' => 'debug','permission' => 0777,'file' => Env::get('root_path') . 'runtime/wechat/wxpay.log',],];$this->app = Factory::payment($config);}

下单

参数释义;

body 备注
out_trade_no 商户内部定单号,不能重复,生成示例见附一
total_fee  金额,
notify_url 回调通知地址,此处设置会覆盖掉配置里面的
 $param = array('body' => '书币','out_trade_no' => $order_info['orderno'],'total_fee' => $order_info['price'],'notify_url' => $_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].'/index/notify/notify','openid' => $_W['user']['base_openid'],);$wxPay = new WXPay();$res = $wxPay->WeixinPrePay($param);return json(['data'=>$res,'error'=>0,'message'=>'']);

WXpay

namespace WXPay;use app\common\model\Members;
use app\common\model\Orders;
use app\common\model\Settlements;
use think\Model;
use EasyWeChat\Payment\Application;
use EasyWeChat\Payment\Order;
use think\Config;
use EasyWeChat\Factory;
use think\facade\Log;
use app\common\model\Setting;
use think\facade\Env;class WXPay
{private $orderModel;private $memberModel;public function __construct(){$configModel = new Setting();$this->orderModel = new Orders();$this->memberModel = new Members();$config = [// 必要配置'app_id' => $configModel->get('ADMIN_APP_ID')->conf_value,'secret' => $configModel->get('ADMIN_SECRET')->conf_value,'mch_id' => $configModel->get('ADMIN_MCH_ID')->conf_value,'key' => $configModel->get('ADMIN_KEY')->conf_value,   // API 密钥// 如需使用敏感接口(如退款、发送红包等)需要配置 API'cert_path' => $configModel->get('ADMIN_CERT_PATH')->conf_value, // XXX: 绝对路径!!!!'key_path' => $configModel->get('ADMIN_KEY_PATH')->conf_value,    // XXX: 绝对路径!!!!'notify_url' => '',     // 可以在下单时单独设置覆盖它'log' => ['level' => 'debug','permission' => 0777,'file' => Env::get('root_path') . 'runtime/wechat/wxpay.log',],];$this->app = Factory::payment($config);}/*** 预支付* @param $data* @param $openid* @return array*/public function WeixinPrePay($data){$attributes = ['body' => $data['body'],'out_trade_no' => $data['out_trade_no'],'total_fee' => $data['total_fee'] * 100,'notify_url' => $data['notify_url'], // 回调地址'trade_type' => 'JSAPI','openid' => $data['openid'],];$result = $this->app->order->unify($attributes);if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {$prepayId = $result['prepay_id'];$jssdk = $this->app->jssdk;$config = $jssdk->sdkConfig($prepayId);   //JSSDK 支付参数$buildConfig = $jssdk->buildConfig(array('chooseWXPay'));  //jssdk 支付配置$json = $jssdk->bridgeConfig($prepayId);  //WeixinJSBridge 支付配置return ['status' => 200, 'msg' => '', 'config' => $config, 'buildConfig' => $buildConfig, 'WeixinJSBridge' => $json];} else {return ['status' => 400, 'msg' => '调起支付失败,请稍后尝试'];}}
$config  jssdk支付参数  
$jssdk->bridgeConfig($prepayId);   WeixinJSBridge 支付配置
$buildConfig   jdsdk配置

html页面发起支付

微信文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

ps:不能拉起支付窗口时请检查当前域名是否在微信商户里js授权列表

1.jssdk 方式

需要先配置  wx.config

<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js" type="text/javascript" charset="utf-8"></script>
<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript" charset="utf-8">wx.config({$buildConfig|raw});
</script>
<body class="bg-secondary"><button class="btn btn-default1 h50 fs18 mt20  layout1 confirm" id="ok">jssdk确认支付</button><button class="btn btn-default1 h50 fs18 mt20  layout1 confirm" id="ok2">JSBridge确认支付</button></body><script>//方式一function onBridgeReady(){WeixinJSBridge.invoke('getBrandWCPayRequest', {$WeixinJSBridge|raw},function(res){if(res.err_msg == "get_brand_wcpay_request:ok" ) {alert("支付成功");//window.location.href="__URL__/user_pay_success&order_id=1";}else{alert(res.errMsg);alert("交易失败,请重试");//window.location.href="__URL__/index?v="+Math.random();}});}$(function(){// 方式二$("#ok").click(function(){wx.chooseWXPay({timestamp: '{$config['timestamp']}',nonceStr: '{$config['nonceStr']}',package: '{$config['package']}',signType: '{$config['signType']}',paySign: '{$config['paySign']}', // 支付签名success: function (res) {if(res.errMsg == "chooseWXPay:ok" ) {alert('支付成功。');//window.location.href="__URL__/user_pay_success&order_id=";}else{alert(res.errMsg);alert("支付失败,请返回重试。");//window.location.href="__URL__/index?v="+Math.random();}},cancel:function(res){}});})$("#ok2").click(function(){onBridgeReady();})})</script>
</html>

2.WeixinJSBridge方式

function onBridgeReady(){WeixinJSBridge.invoke('getBrandWCPayRequest', {$rspArray['payinfo']},function(res){     if(res.err_msg == "get_brand_wcpay_request:ok" ) {// alert("支付成功");window.location.href="__URL__/user_pay_success&order_id={$order['id']}";}else{alert("交易失败,请重试");window.location.href="__URL__/index?v="+Math.random();}}); }//官方示例
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();
}

支付成功回调

此处根据订单号识别订单类型,然后执行各自逻辑,当没有回复微信时,微信会多次发通知,所以在此处要判断是否处理过,避免重复购买

$order = $this->getInfoByOrderNo($message['out_trade_no']);
if (!$order || $order['status'] == 1) { // 如果订单不存在 或者 订单已经支付过了return true;
}
 /*** Notes:支付回调,根据订单号前两位判断交易类型,然后交给相应Model处理* @author:xxf* Date: 2018/5/8* Time: 14:46* @param $type 支付类型* @throws \EasyWeChat\Kernel\Exceptions\Exception*/public function notify(){$response = $this->app->handlePaidNotify(function ($message, $fail) {Log::info('微信支付回调:' . json_encode($message));if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态// 用户是否支付成功if ($message['result_code'] === 'SUCCESS') {$type = substr($message['out_trade_no'], 0, 2); //订单号前两位判断支付场景,CX促销活动,CZ普通充值switch ($type) {case 'CZ';$this->orderModel->payRechargeNotify($message);break;case 'CX';$this->orderModel->payActivityNotify($message);break;default:return $fail('单号异常,请稍后再通知我');break;}// 用户支付失败} elseif ($message['result_code'] === 'FAIL') {//db('user_orders')->where('id',$message['out_trade_no'])->update('status',7);}} else {return $fail('通信失败,请稍后再通知我');}return true; // 返回处理完成});$response->send();}

到此 支付完成

企业付款

企业付款,退款,发送红包等接口必须配合证书路径

public function payToBalance($data){$data = array('partner_trade_no' => $data['partner_trade_no'], // 商户订单号'openid' => $data['openid'],'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名're_user_name' => $data['realname'],'amount' => $data['amount'] * 100, // 付款金额,单位为分'desc' => $data['desc'], // 付款操作说明信息。必填);$result = $this->app->transfer->toBalance($data);Log::info('付款到余额:' . json_encode($result));return $result;}

付款到 红包,银行卡相关接口

WXpay.php

<?phpnamespace app\wechatPay;use think\Model;
use EasyWeChat\Payment\Application;
use EasyWeChat\Payment\Order;
use think\Config;
use EasyWeChat\Factory;
use think\Log;class Wxpay
{public function __construct(){$config = [// 必要配置'app_id' => 'wxc0330dcea20','secret' => 'c96af09b','mch_id' => '14963','key' => '7c44f0413daljoeihoandjnaahdhawee',   // API 密钥// 如需使用敏感接口(如退款、发送红包等)需要配置 API'cert_path' => ROOT_PATH . 'public/wechat/apiclient_cert.pem', // XXX: 绝对路径!!!!'key_path' => ROOT_PATH . 'public/wechat/apiclient_key.pem',    // XXX: 绝对路径!!!!'notify_url' => '/user/index/notify',     // 可以在下单时单独设置覆盖它'log' => ['level' => 'debug','permission' => 0777,'file' => ROOT_PATH . 'runtime/wechat/wxpay.log',],];$this->app = Factory::payment($config); }/*** 预支付* @param $data* @param $openid* @return array*/public function WeixinPrePay($data, $openid){Log::init(['type' => 'File','path' => APP_PATH . 'logs/']);$attributes = ['body' => $data['body'],'out_trade_no' => $data['out_trade_no'],'total_fee' => $data['total_fee'] * 100,'notify_url' => $data['notify_url'], // 回调地址'trade_type' => 'JSAPI','openid' => $openid,];$result = $this->app->order->unify($attributes);Log::info('微信支付参数:' . json_encode($attributes));Log::info('支付结果:' . json_encode($result));if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {$prepayId = $result['prepay_id'];$jssdk = $this->app->jssdk;$config = $jssdk->sdkConfig($prepayId);   //JSSDK 支付参数$buildConfig = $this->app->jssdk->buildConfig(array('chooseWXPay'));  //jssdk 支付配置$json = $jssdk->bridgeConfig($prepayId);  //WeixinJSBridge 支付配置return ['status' => 200, 'msg' => '', 'data' => $config, 'buildConfig' => $buildConfig, 'WeixinJSBridge' => $json];} else {return ['status' => 400, 'msg' => '调起支付失败,请稍后尝试'];}}public function buildConfig(){$buildConfig = $this->app->jssdk->buildConfig(array('chooseWXPay'));  //jssdk 配置return $buildConfig;}/*** 提现到余额* Notes:* @author:xxf* Date: 2018/5/8* Time: 14:11* @param $data* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException*/public function payToBalance($data){$data = array('partner_trade_no' => $data['partner_trade_no'], // 商户订单号'openid' => $data['openid'],'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名're_user_name' => $data['realname'],'amount' => $data['amount'] * 100, // 付款金额,单位为分'desc' => $data['desc'], // 付款操作说明信息。必填);$result = $this->app->transfer->toBalance($data);Log::info('付款到余额:' . json_encode($result));return $result;}/*** 查询付款到零钱的订单* @param $partnerTradeNo* @author xingxiong.fei@163.com* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException*/public function getToBalanceOrder($partnerTradeNo){$result = $this->app->transfer->queryBalanceOrder($partnerTradeNo);return $result;}/*** 付款到银行卡* @author xingxiong.fei@163.com* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException*/public function payToBankCard(){$result = $this->app->transfer->toBankCard(['partner_trade_no' => '1229222022','enc_bank_no' => '6214830901234564', // 银行卡号'enc_true_name' => 'cc',   // 银行卡对应的用户真实姓名'bank_code' => '1001', // 银行编号'amount' => 100,  // 单位:分'desc' => '测试',]);return $result;}/*** 付款到银行查询* @param $partnerTradeNo* @author xingxiong.fei@163.com* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException*/public function getToBankCardOrder($partnerTradeNo){return $this->app->transfer->queryBankCardOrder($partnerTradeNo);}/*** Notes:发送红包* Date: 2019/6/26* Time: 11:03* @return mixed*/public function redPacket(){$redpackData = ['mch_billno'   => 'xy123456','send_name'    => '测试红包','re_openid'    => 'oxTWIuGaIt6gTKsQRLau2M0yL16E','total_num'    => 1,  //固定为1,可不传'total_amount' => 100,  //单位为分,不小于100'wishing'      => '祝福语','client_ip'    => '192.168.0.1',  //可不传,不传则由 SDK 取当前客户端 IP'act_name'     => '测试活动','remark'       => '测试备注',// ...];$result = $this->app->redpack->sendNormal($redpackData);return $result;}/*** Notes:支付回调* @author:xxf* Date: 2018/5/8* Time: 14:46* @param $type 支付类型* @throws \EasyWeChat\Kernel\Exceptions\Exception*/public function notify(){Log::init(['type' => 'File','path' => APP_PATH . 'logs/']);$response = $this->app->handlePaidNotify(function ($message, $fail) {Log::info('微信支付回调:' . json_encode($message));$type = substr($message['out_trade_no'], 0, 2); //订单号前两位判断何种支付,CC乘车 BX保险 YH购买优惠券 BZ 保证金//每日收入$date = date("Y-m-d", time());$temp = db('profit_day')->where('day', $date)->find();if (!$temp){$data['day'] = $date;db('profit_day')->insert($data);}/*if ($type == 'CC'){$order = db('user_orders')->where('order_number',$message['out_trade_no'])->find();}$order = db('user_orders')->where('order_number',$message['out_trade_no'])->find();if (!$order || $order['status']==7) { // 如果订单不存在 或者 订单已经支付过了return true;}*/if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态// 用户是否支付成功if ($message['result_code'] === 'SUCCESS') {switch ($type) {case 'CC';$order = db('user_orders')->where('order_number', $message['out_trade_no'])->find();if (!$order || $order['orderStatus'] == 6) { // 如果订单不存在 或者 订单已经支付过了return true;}db('user_orders')->where('order_number', $message['out_trade_no'])->update(['orderStatus' => 6]);db('profit_day')->where('day', $date)->setInc('pay_profit', $message['total_fee']/100);break;case 'YH';$order = db('coupon_user')->where('order_number', $message['out_trade_no'])->find();if (!$order || $order['status'] == 1) {return true;}db('coupon_user')->where('order_number', $message['out_trade_no'])->update(['status' => 1]);db('profit_day')->where('day', $date)->setInc('coupon_profit', $message['total_fee']/100);break;case 'BZ';$order = db('bail')->where('order_number', $message['out_trade_no'])->find();if (!$order || $order['status'] == 1) {return true;}db('bail')->where('order_number', $message['out_trade_no'])->update(['pay_status' => 1]);db('user')->where('uid', $order['uid'])->setInc('cancel_times');break;case 'BX';$order = db('insurance_user')->where('order_number', $message['out_trade_no'])->find();if (!$order || $order['status'] == 1) {return true;}db('insurance_user')->where('order_number', $message['out_trade_no'])->update(['status' => 1]);db('profit_day')->where('day', $date)->setInc('insurance_profit', $message['total_fee']/100);break;}/*db('user_orders')->where('order_number',$message['out_trade_no'])->update(['status' => 7]);*/// 用户支付失败} elseif ($message['result_code'] === 'FAIL') {//db('user_orders')->where('id',$message['out_trade_no'])->update('status',7);}} else {return $fail('通信失败,请稍后再通知我');}return true; // 返回处理完成});$response->send();}}

附一  生成订单号

/*** 生成订单号* Time: 11:15* @param $type 订单类型* @return string*/
function makeOrdersn($type='')
{@date_default_timezone_set("PRC");//订单号码主体(YYYYMMDDHHIISSNNNNNNNN)$order_id_main = $type.date('YmdHis') . rand(10000000,99999999);$order_id_len = strlen($order_id_main);$order_id_sum = 0;for($i=0; $i<$order_id_len; $i++){$order_id_sum += (int)(substr($order_id_main,$i,1));}//唯一订单号码(YYYYMMDDHHIISSNNNNNNNNCC)$order_id = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100,2,'0',STR_PAD_LEFT);return $order_id;
}

thinkPHP+easyWeChat开发微信公众号支付,企业付款,红包相关推荐

  1. asp源码demo下载:微信公众号支付企业付款到零钱功能asp源码下载案例

    最近接到一个开发需求,一个企业想用微信支付里面的,企业付款到零钱功能,利用此功能来给用会发红包,因为微信支付里的红包功能一次要付款1块钱,太多,所以他想利用此功能来发红包,这样红包金额可以低到每次3角 ...

  2. java开发微信公众号支付

    这篇文章主要给大家结合微信支付接口开发的实践,从获取用户授权到各主要接口的使用方法等方面介绍微信支付的关键点技术,有需要的小伙伴可以参考下 最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时 ...

  3. 开发微信公众号支付代码

    一. url传入当前页面url地址或者微信公众平台配置的域名根目录,使用window.location.href方法获取, 二. 下面代码请结合微信公众号开发文档 微信公众号开发文档 function ...

  4. 微信公众号支付java前后端分离开发

    微信公众号支付java前后端分离开发 微信公众号支付java前后端分离开发 我们开发的是基于河北银行的支付,支付宝微信都做了,这里就介绍一下微信公众号支付,这个公众号支付需要配置的东西太多了,官方文档 ...

  5. 微信公众号支付开发全过程(java版)

    文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号:好好学java,获取优质学习资源. 一.微信官方文档微信支付开发流程(公众号支付) 首先我们到微信支付的官方文档的开发步骤部分查 ...

  6. php调用微信公众号支付接口,Thinkphp微信公众号支付接口

    本文实例为大家分享了Thinkphp微信公众号支付接口,供大家参考,具体内容如下 第一步 先把文件夹的那两个图片 配置成一样的路径 除了域名要改 其他保持一致. 第二步  把 Weixinpay 这个 ...

  7. 微信公众号支付开发手记(node)

    微信支付 前言 总结一下最近业务开发中对微信公众号支付的开发过程,微信支付的开发前提是已经具备可上线微信公众号开发的基础上进行的,如果你的开发阶段目前停留在起步,建议参考这篇文章开始. 好了,来聊一聊 ...

  8. 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。

    最近公司开发网站针对微信公众号的支付功能. 由于公司目前的这个项目网站是使用asp代码开发的,但是微信官方给出的demo中是没有asp版本的,所以楼主只有下载demo的php版本作为参考写了一个asp ...

  9. 微信支付开发教程(公众号支付)

    前段时间公司电商项目需要接入微信支付,因此研究了一下如何使用微信支付.和支付宝支付相比,微信支付相对复杂一些,需要配置的东西更多,限制也更多.经过两天的研究,终于搞定微信支付,在这里对于使用微信支付的 ...

最新文章

  1. EMC开发实习生电面经验
  2. 【WebAPI No.5】Core WebAPI中的自定义格式化
  3. There are no packages available for install
  4. GeoServer之styles定制
  5. Django REST framework+Vue 打造生鲜超市(六)
  6. mysql 用户名中主机$_phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接。您应当检查配置文件中的主机、用户名和密码,...
  7. avframe转byte数组_C# amp; VB6.0 图像与二维数组 互转
  8. oracle控制文件全备失败,Oracle数据库案例整理-恢复数据库失败-主备机控制文件所在目录不同...
  9. STRUTS学习笔记
  10. 深刻揭露步态识别的“谎言”(篇一)
  11. Tomcat JAAS 身份验证和授权
  12. 一个有趣的555定时电路,有点意思哈哈
  13. gift to me by myself on 2012's new year
  14. 使用JavaScript实现省市县三级联动
  15. Unity WebGL部署
  16. ceph 运维操作 - POOL
  17. α波、β波、θ波和δ波
  18. canvas 实现流星雨特效
  19. 元气骑士卡无限服务器,元气骑士养剑葫怎么卡无限飞剑bug方法介绍
  20. 汉诺塔代码图文详解(递归入门)

热门文章

  1. Spring Boot中连接Redis的yml WRONGPASS invalid username-password pair or user is disabled.
  2. pytorch的深度Ritz方法入门
  3. Spring Boot底层原理详解及整合
  4. manjaro xfce桌面 Terminal终端显示字体间距过大的解决办法
  5. Ubuntu 18.04下创建新用户/目录、修改用户权限及删除用户的方法
  6. python 建筑物信息_如何巧用Python和ELK瞬间完成总图建筑名称标注?
  7. 有风才是真的狂:内置风扇的电竞手机你见过么?
  8. JavaScript--Cookie
  9. 德国大陆轮胎Continental EDI 项目案例
  10. vmware配置linux虚拟机与windows共享存储