<?php

namespace app\api\controller\v1;

use think\Request;
use app\api\exception\weappay\lib\WxPayConfig;
use app\common\model\StoreMessages as Smsg; //消息
use app\common\model\StoreSpecial as Ss; // 特价商品
use app\common\model\StoreGroup as SG; //拼团
use app\common\model\StoreMgroup as SM; //用户团购
use app\common\model\StoreMspecial as SMs; //用户限量
use app\common\model\StoreOrder as StoreOd; //订单
use app\common\model\StoreCart as shopCart; //购物车
use app\common\model\StoreProducts as StorePro; //普通商品
use think\facade\Log;
use app\api\controller\v1\PayConfig; //微信支付管理
class Wxpay extends PayConfig
{
public function wxappay() //微信app支付
{
$oid = input('oid'); //商家id
$orsid = input('orsid'); //订单号
$price = input('price');
$appid = PayConfig::get_wx_config_info('wxappid', $oid);
$mchid = PayConfig::get_wx_config_info('wxmch_id', $oid);
//$price = $price * 100;
$price = 1;
$nonce_str = self::getNonceStr(); //自己做个随机字符串 $data = [
'appid' => $appid, //appid T
'mch_id' => $mchid, //商户号T
'nonce_str' => $nonce_str,
'body' => '可待商城系统-商品购买', //商品信息
'out_trade_no' => $orsid, //订单号
'total_fee' => $price, //价格,微信支付价格会处以一百
'spbill_create_ip' => self::getip(),
'notify_url' => config('api_url') . '/wxnotify',
'trade_type' => 'APP', //小程序,app,之类的选项不一样
]; $data['sign'] = self::makeSign($data, $oid); //制作签名 $xmldata = self::array2xml($data); //传入参数转换成xml格式
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$res = self::curl_post_ssl($url, $xmldata); //curl发出请求 if (!$res) {
return ['status' => 1, 'msg' => "服务器连接失败"];
} $content = self::xml2array($res); //签名失败时,打印该数据 //
if (strval($content['return_code']) == 'FAIL') {
return json(['status' => 1, 'msg' => strval($content['return_msg'])]);
} if (strval($content['result_code']) == 'FAIL') {
return json(['status' => 1, 'msg' => strval($content['err_code']), ':' . strval($content['err_code_des'])]);
} //第二次签名,把第一次签名成功微信传过来的数据参数加入第二次签名,prepayid
$timest = (string)time(); $resdata = [
'appid' => $appid,
'partnerid' => $mchid,
'prepayid' => strval($content['prepay_id']),
'package' => 'Sign=WXPay',
'noncestr' => self::getNonceStr(),
'timestamp' => $timest,
]; $resdata['sign'] = self::makeSign($resdata, $oid); //T同第一次,使用当前时间和随机字符串获取签名
return json(['data' => $resdata, 'code' => 1]); //把数据传给前端,调起支付 } //回调地址(逻辑处理)
public function wxnotify()
{
$notify = file_get_contents("php://input");
$array = $this->xml2array($notify); //微信回调数据是xml格式,转化成数组
$order_num = $array['out_trade_no'];
$paynumber = $array["transaction_id"]; //交易流水号
$price = $array["total_amount"]; //支付金额
//$price = 0.01; //支付金额
}
//制作字符串
public function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
} //制作签名,需要支付密钥
public function makeSign($data, $oid = 0)
{
//获取微信支付秘钥
$key = PayConfig::get_wx_config_info('wxkey', $oid);;
// 去空
$data = array_filter($data);
//签名步骤一:按字典序排序参数
ksort($data);
$string_a = http_build_query($data);
$string_a = urldecode($string_a);
//签名步骤二:在string后加入KEY
//$config=$this->config;
$string_sign_temp = $string_a . "&key=" . $key;
//签名步骤三:MD5加密
$sign = md5($string_sign_temp);
// 签名步骤四:所有字符转为大写
$result = strtoupper($sign);
return $result;
} //获得用户IP
public function getip()
{
static $ip = '';
$ip = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_CDN_SRC_IP'])) {
$ip = $_SERVER['HTTP_CDN_SRC_IP'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) and preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] as $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
} /**
* 将一个数组转换为 XML 结构的字符串
* @param array $arr 要转换的数组
* @param int $level 节点层级, 1 为 Root.
* @return string XML 结构的字符串
*/
public function array2xml($arr, $level = 1)
{
$s = $level == 1 ? "<xml>" : '';
foreach ($arr as $tagname => $value) {
if (is_numeric($tagname)) {
$tagname = $value['TagName'];
unset($value['TagName']);
}
if (!is_array($value)) {
$s .= "<{$tagname}>" . (!is_numeric($value) ? '<![CDATA[' : '') . $value . (!is_numeric($value) ? ']]>' : '') . "</{$tagname}>";
} else {
$s .= "<{$tagname}>" . $this->array2xml($value, $level + 1) . "</{$tagname}>";
}
}
$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
return $level == 1 ? $s . "</xml>" : $s;
} /**
* 将xml转为array
* @param string $xml xml字符串
* @return array 转换得到的数组
*/
public function xml2array($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(false);
$result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
} //用于支付
public function curl_post_ssl($url, $xmldata, $second = 30, $aHeader = array())
{
$ch = curl_init();
//超时时间
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
if (count($aHeader) >= 1) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
} curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xmldata);
$data = curl_exec($ch);
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
} //数组转xml
function arrayToXml($arr)
{
$xml = "<root>";
foreach ($arr as $key => $val) {
if (is_array($val)) {
$xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
} else {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
}
}
$xml .= "</root>";
return $xml;
}
}

  

app微信支付的更多相关文章

  1. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  2. APP微信支付报错《商户号该产品权限未开通,请前往商户平台>产品中心检查后重试》

    问题 最近项目使用MUI,HBuilder.开发打包H5的app 在开发H5 plus支付的时候,遇到以下问题: App微信支付调官方的统一下单接口返回错误信息 {return_msg=商户号该产品权 ...

  3. ThinkPHP5.0 实现 app微信支付功能

    相对于之前随笔写的<ThinkPHP5.0实现app支付宝支付功能>来说,php对接app微信支付功能就相对简单的多了,最近有加我的朋友问到app微信支付,所以我把app微信支付的demo ...

  4. app微信支付(一) - 微信支付基本业务流程解析

    想必微信支付是现在很多朋友离不开的一个功能,不论是扫描支付还是公众号支付或者app端支付,基本的思路都是一样的,之前做过支付宝支付以及中国移动支付接口,这几天花时间讲讲微信支付吧 先看一下微信支付的时 ...

  5. 手机app微信支付后台处理流程

    第一步:客户在手机app确认订单,提交订单后,app将订单详情传给后台,后台将订单存入数据库,将存入数据库的id返回给app. 第二步:这时候手机端app会让客户选择哪种付款方式,我们做的是微信,所以 ...

  6. thinkPHP实现APP微信支付

    控制器 class Pay extends Controller { const WX_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifie ...

  7. app微信支付-java服务端接口 支付-查询-退款

    个人不怎么看得懂微信的文档,看了很多前辈的写法,终于调通了,在这里做一下记录. 首先来定义各种处理类(微信支付不需要特殊jar包,很多处理需要自己封装,当然也可以自己写完打个jar包) 参数要用jdo ...

  8. APP微信支付Java后台的实现(springmvc)

    第一次做微信支付,阅读完开发文档后,下了个官方demo,摸索了好久,期间也出现了好多问题,终于是实现生成预支付订单以及支付成功后接收微信服务器通知,不多说了,直接上代码: 一.工具类 Constant ...

  9. java中微信统一下单采坑(app微信支付)

    app支付前java后台统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1 微信支付接口签名校验工具:https ...

  10. APIcloud制作APP 微信支付与支付宝支付

    首先要在云端绑定相应模块如alipay和wxpay其次编写代码. 配置区域 var cfg = { webName:'',//APP名字 payDebug:true, isUseWxPay:true, ...

随机推荐

  1. centos 6.5 搭建DHCP实验

    搭建DHCP服务 安装DHCP服务 挂载光盘:mount /dev/cdrom /qswz 从光盘的安装包中安装DHCP rpm -ivh dhcp-4.1.1-38.P1.el6.centos.i6 ...

  2. input上传按钮的优化

    在使用input标签按钮的时候,<input type="file" value="" /> 显示很难看,怎么办? 使用label <li c ...

  3. nginx部署成功却没有办法访问

    1.首要想到的问题是防火墙没关 注意:因为centos7.0默认不是使用iptables方式管理,而是firewalld方式.CentOS6.0防火墙用iptables管理. 2.解决: ①首先查看防 ...

  4. HTML连载37-边框属性(下)、边框练习

    一.边框属性 1.连写(分别设置四条边的边框) border-width:上 右 下 左: border-style:上 右 下 左: border-color:上 右 下 左: 注意点: (1)这三 ...

  5. 02 (OC)* ViewController 的声明周期

    一. UIViewController 的 生命周期 代码 示例 #pragma mark --- life circle // 非storyBoard(xib或非xib)都走这个方法 - (inst ...

  6. [Pandas] 02 - Tutorial of NumPy

    Ref: NumPy 教程 这里主要是查缺补漏一些常用方法. 初步认识 矩阵常见知识点 矩阵操作 Ref: [Python] 01 - Number and Matrix[总结过一部分] 一.矩阵 ( ...

  7. hibernate保存中文mysql

    最近自己做测试的时候,发现中文入库成?号了,不由得想到是否某处编码设置问题. 1.检查数据库是否为utf8 2.检查配置文件,数据库链接地址是否指定编码,经检查本地配置文件 jdbc.url=jdbc ...

  8. Mybatis源码解析,一步一步从浅入深(六):映射代理类的获取

    在文章:Mybatis源码解析,一步一步从浅入深(二):按步骤解析源码中我们提到了两个问题: 1,为什么在以前的代码流程中从来没有addMapper,而这里却有getMapper? 2,UserDao ...

  9. Codeforces Numbers 题解

    这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...

  10. 程序员接触新语言————hello world ^-^,web3种样式表

    我的第一个网页 <!DOCTYPE html> <html> <head lang="en"> <meta charset="U ...