<?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. AOE工程实践-银行卡OCR里的图像处理

    作者:杨科 近期我们开发了一个银行卡 OCR 项目.需求是用手机对着银行卡拍摄以后,通过推理,可以识别出卡片上的卡号. 工程开发过程中,我们发现手机拍摄以后的图像,并不能满足模型的输入要求.以 And ...

  2. springmvc 全局异常解决方案

    系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生. 系统的dao.service. ...

  3. 【Mac】快速复制文件路径

    一.使用Automator新建服务 二.配置 三.使用 四.创建快捷键 一.使用Automator新建服务 在应用程序文件夹里打开Automator,选择文件菜单,新建一个服务,如下  二.配置 在 ...

  4. NGINX的启停命令、以及动态加载配置文件的命令

    -- 启动(不推荐):在nginx目录下有一个sbin目录,sbin目录下有一个nginx可执行程序../nginx -- 启动(指定配置文件,推荐)/usr/local/nginx/sbin/ngi ...

  5. IDEA中工程上传到SVN

    1.先在IDEA上集成SVN 2.查看SVN仓库:连接SVN ①此时应该先去SVN服务器中新建一个SVN服务: 点击下一步 点击下一步 点击create ②查看SVN仓库 先复制SVN的地址 把复制的 ...

  6. Spring Boot 多环境如何配置

    Spring Boot 开发环境.测试环境.预生产环境.生产环境多环境配置 通常一个公司的应程序可能在开发环境(dev).测试环境(test).生产环境(prod)中运行.那么是不是需要拷贝不同的安装 ...

  7. .Net基础篇_学习笔记_第四天_加加减减

    using System.Linq; using System.Text; using System.Threading.Tasks; namespace 第四天_加加减减 { class Progr ...

  8. Hive的动态分区

    关系型数据库(如Oracle)中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition), ...

  9. 一文读懂NodeJS全栈开发利器:CabloyJS(万字长文)

    目录 0 修订 0.1 修订说明 0.2 修订历史 1 基本概念 1.1 CabloyJS是什么 1.2 CabloyJS核心解决什么问题 1.3 CabloyJS的开发历程 2 数据版本与开发流程 ...

  10. C++ std::thread概念介绍

    C++ 11新标准中,正式的为该语言引入了多线程概念.新标准提供了一个线程库thread,通过创建一个thread对象来管理C++程序中的多线程. 本文简单聊一下C++多线程相关的一些概念及threa ...