app微信支付
2024-08-26 01:54:01
<?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;
}
}
最新文章
- jquery实现";跳到底部";,";回到顶部";效果
- Xcode + Swift 制作动态原型
- 分享一个基于EF5.0封装的BaseDAL
- SpatiaLite 各版本数据库差异
- 在Android应用中实现Google搜索的例子
- C趣味100道之58.拉丁方的一些想法。
- HDU 5765 Bonds(状压DP)
- hive------ Group by、join、distinct等实现原理
- oracle 中 某个字段的长度不够的sql 语句
- svg中实现文字随曲线走向,HTML直接写和JavaScript创建对象两种方式
- CRM项目之stark组件(2)
- node通过http.request向其他服务器上传文件
- eclipse spring 配置文件xml校验时,xsd报错
- Dom操作注意事项
- Java性能调优:利用JMC分析性能
- javascript对象使用总结
- rim
- 2018.07.27 bzoj3064: Tyvj 1518 CPU监控(线段树)
- ACM-ICPC 2018 徐州赛区网络预赛 Solution
- 1029 C语言文法翻译(2)