微信app支付 ci框架做的
/**
* 组合微信app支付 获得prepayid
* @param int $order_num
*/
private function _wxpay_request($order_num = 0)
{
//判断订单编号必须是数组并且不为0
check_order_num($order_num);
//引入微信支付类
libraries_include("wxpay/", "WxPayHelper.app.php");
//支付接口发起url
$pay_url = $this->config->item("PAY_URL");
//通知地址
$notify_url = $this->config->item("WEIXIN_NOTIFY_URL");
//微信配置
$pay_config = $this->config->item("WEIXIN_PAY_NEED");
$helper = new WxPayHelper();
//随机字符串
$nonce_str = $helper->getRandChar(32);
//获得订单数据
$order_data = $this->order_model->get_one($order_num);
$data["appid"] = $pay_config['appid'];//微信开放平台审核通过的应用APPID
$data["body"] = $pay_config['body'];//商品或支付单简要描述
$data["mch_id"] = $pay_config['mch_id'];//商户号
$data["nonce_str"] = $nonce_str;//随机字符串
$data["notify_url"] = $notify_url;//通知地址
$data["out_trade_no"] = $order_data["order_num"];//商户订单号
$data["spbill_create_ip"] = $helper->get_client_ip();//终端IP
$data["total_fee"] = $order_data['total'] * 100;//总金额
$data["trade_type"] = "APP";//交易类型
$data["sign"] = $helper->getSign($data, $pay_config['partner']);//签名
$xml = $helper->arrayToXml($data);
$response = $helper->postXmlCurl($xml, $pay_url);
//将微信返回的结果xml转成数组
$responseArr = $helper->xmlToArray($response);
if(isset($responseArr["return_code"]) && $responseArr["return_code"]=='SUCCESS' && isset($responseArr['result_code']) && $responseArr["result_code"]=='SUCCESS'){
$data_pay["appid"] = $pay_config['appid'];
$data_pay["noncestr"] = $nonce_str;
$data_pay["package"] = "Sign=WXPay";
$data_pay["partnerid"] = $pay_config['mch_id'];
$data_pay["prepayid"] = $responseArr['prepay_id'];
$data_pay["timestamp"] = time();
$data_pay["sign"] = $helper->getSign($data_pay, $pay_config['partner']);//二次签名
$this->response = array('status'=>0, 'msg'=>'success', 'data'=>$data_pay);
}else{
$return_msg = $responseArr['err_code_des'];
$this->response = array('status'=>0, 'msg'=>$return_msg, 'data'=>$responseArr);
}
}
//helper.php
<?php
class WxPayHelper{
/**
* 验证签名
* @param array $data
* @param string $key
* @return string
*/
function getVerifySign($data, $key)
{
$String = $this->formatParameters($data, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . $key;
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result = strtoupper($String);
return $result;
}
function formatParameters($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if($k=="sign"){
continue;
}
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
/**
* 得到签名
* @param object $obj
* @param string $api_key
* @return string
*/
function getSign($obj, $api_key)
{
foreach ($obj as $k => $v)
{
$Parameters[strtolower($k)] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String."&key=".$api_key;
//签名步骤三:MD5加密
$result = strtoupper(md5($String));
return $result;
}
/**
* 获取指定长度的随机字符串
* @param int $length
* @return Ambigous <NULL, string>
*/
function getRandChar($length){
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol)-1;
for($i=0;$i<$length;$i++){
$str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
return $str;
}
/**
* 数组转xml
* @param array $arr
* @return string
*/
function arrayToXml($arr)
{
header("Content-type: text/xml");
$xml = '<xml>';
foreach ($arr as $key=>$val)
{
if (is_numeric($val))
{
$xml.="<".$key.">".$val."</".$key.">";
}
else
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
$xml.= '</xml>';
return $xml;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
* @throws WxPayException
*/
function postXmlCurl($xml, $url, $second=30, $useCert=false, $sslcert_path='', $sslkey_path='')
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch,CURLOPT_URL, $url);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
if($useCert == true){
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $sslcert_path);
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $sslkey_path);
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
return false;
}
}
/**
* 获取当前服务器的IP
* @return Ambigous <string, unknown>
*/
function get_client_ip()
{
if (isset($_SERVER['REMOTE_ADDR'])) {
$cip = $_SERVER['REMOTE_ADDR'];
} elseif (getenv("REMOTE_ADDR")) {
$cip = getenv("REMOTE_ADDR");
} elseif (getenv("HTTP_CLIENT_IP")) {
$cip = getenv("HTTP_CLIENT_IP");
} else {
$cip = "127.0.0.1";
}
return $cip;
}
/**
* 将数组转成uri字符串
* @param array $paraMap
* @param bool $urlencode
* @return string
*/
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;
}
/**
* XML转数组
* @param unknown $xml
* @return mixed
*/
function xmlToArray($xml)
{
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
}
?>
//异步通知
/**
* 微信消息地址
*/
public function weixin_notify()
{
libraries_include("wxpay/", "WxPayHelper.app.php");
$helper = new WxPayHelper();
//微信配置
$pay_config = $this->config->item("WEIXIN_PAY_NEED");
$xml = file_get_contents("php://input");
if(!$xml){
exit('<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>');
}
$wx_back = $helper->xmlToArray($xml);
if(empty($wx_back)){
exit('<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>');
}
$checkSign = $helper->getVerifySign($wx_back, $pay_config['partner']);
//验证签名
if($checkSign==$wx_back['sign']){
if (isset($wx_back['result_code']) && $wx_back['result_code']=='SUCCESS') {
$requestReturnData = file_get_contents("php://input");
//商户订单号
$out_trade_no = $wx_back['out_trade_no'];
//第三方订单编号
$third_order_num = $wx_back["transaction_id"];
//交易状态
$trade_status = $wx_back['result_code'];
//订单金额 保留小数点后两位
$total_fee = sprintf("%.2f", $wx_back['total_fee']/100);
//公司业务处理
//处理后同步返回给微信
exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
}
}
exit('<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>');
}
微信app支付 ci框架做的的更多相关文章
- 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付
在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...
- H5使用codovar插件实现微信支付(微信APP支付模式,前端)
H5打包的app实现微信支付及支付宝支付,本章主要详解微信支付,支付宝支付请查看另一篇“H5使用codovar插件实现支付宝支付(支付宝APP支付模式,前端)” ps:本文只试用H5开发的,微信 AP ...
- Android版-微信APP支付
首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...
- 微信APP支付【签名失败】
最近在做微信APP支付 遇到一个问题 请求预下单时,接口返回签名错误 由于之前没有成功的交互,刚开始检查程序的错误,经过多次修改,发现依然是签名错误,可能出现的问题如下: 1.该签名密钥不是AppSe ...
- 微信app支付返回-1的问题
我也是被坑就当留个纪念 前两天查了各种关于微信app支付返回-1的都是ERR_COMM 问题然后各种 验证最后还是误解 第三天去验证了一下微信开放平台发现了问题 appid 不在同一个开放平台 项目之 ...
- .Net后台实现微信APP支付
上一节分享了微信小程序支付的后台,这一节来分享一下微信APP支付的后台.微信APP支付和微信小程序差别不大,微信APP支付后台不需要微信登录凭证.后台下单时交易类型(trade_type)不再是&qu ...
- .net 微信APP支付接口的开发流程以及坑
流程 申请APP的微信支付 申请成功之后得到APPID 商户号 以及自己设置商户号的支付密码 这时就可以开发接口了 微信APP支付API:https://pay.weixin.qq.com/wiki/ ...
- 微信app支付android客户端以及.net服务端实现
由于公司运营需要,需要在客户端(android/ios)增加微信以及支付宝支付,在调用微信app支付时遇到一些问题,也算是一些踩过的坑,记录下来 ,希望能对.net开发者服务端网站更快的集成微信app ...
- php开发微信APP支付接口
之前在开发APP中用到了微信支付,因为是第一次用,所以中途也遇到了好多问题,通过查看文档和搜集资料,终于完成了该功能的实现.在这里简单分享一下后台php接口的开发实例. 原文地址:代码汇个人博客 ht ...
随机推荐
- python常用模块
os模块 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os ...
- 二、Redis基本操作——String(实战篇)
小喵万万没想到,上一篇博客,居然已经被阅读600次了!!!让小喵感觉压力颇大.万一有写错的地方,岂不是会误导很多筒子们.所以,恳请大家,如果看到小喵的博客有什么不对的地方,请尽快指正!谢谢! 小喵的唠 ...
- JavaScript权威设计--事件处理介绍(简要学习笔记十七)
1.事件相关概念 事件类型:一个用来说明发生什么类型事件的字符串 事件目标:是发生的事件或与之相关的对象. 事件处理程序(事件监听程序):是处理货响应事件的函数. 事件对象:是与特定事件相关并且包含有 ...
- SQL Server-交叉联接、内部联接基础回顾(十二)
前言 本节开始我们进入联接学习,关于连接这一块涉及的内容比较多,我们一步一步循序渐进学习,简短内容,深入的理解,Always to review the basics. 交叉联接(CROSS JOIN ...
- .net 分布式架构之分布式锁实现
分布式锁 经常用于在解决分布式环境下的业务一致性和协调分布式环境. 实际业务场景中,比如说解决并发一瞬间的重复下单,重复确认收货,重复发现金券等. 使用分布式锁的场景一般不能太多. 开源地址:http ...
- spring boot(五):spring data jpa的使用
在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...
- JS处理事件小技巧
今天,就分享一下我自己总结的一些JS的小技巧: ①防止鼠标选中事件 <div class="mask" onselectstart="return false&qu ...
- 【Big Data】HADOOP集群的配置(二)
Hadoop集群的配置(二) 摘要: hadoop集群配置系列文档,是笔者在实验室真机环境实验后整理而得.以便随后工作所需,做以知识整理,另则与博客园朋友分享实验成果,因为笔者在学习初期,也遇到不少问 ...
- Linux 平台静默安装 Oracle客户端
需求:Linux平台,安装完整版Oracle客户端 Tips:如果只是用到sqlldr,sqlplus功能,可以参考<Linux上oracle精简版客户端快速部署>快速部署精简版:如果需要 ...
- 安卓第一次启动引导页使用ViewPager实现
我们在安装某个APP的时候,基本都会有一个引导页的提示,他们可以打广告,或者介绍新功能的加入和使用说明等.一般都支持滑动并且下面有几个点,显示共有多少页和当前图片的位置,在IOS上这个实现起来比较简单 ...