weizong song 5 years ago
parent 41d272311a
commit de97de8334

@ -6,6 +6,7 @@ namespace App\Http\Controllers\Manager;
use AlicFeng\IdentityCard\InfoHelper;
use App\Customer;
use App\Events\OrderAssigned;
use App\Libs\WxMicroPay;
use App\Models\Approval;
use App\Models\ApprovalItems;
use App\Models\Area;
@ -100,7 +101,7 @@ class OrdersController extends CommonController
/**
* @OA\Get(
* path="/manager/get-badges",
* summary="获取首页数量角标",
* summary="V2-获取首页数量角标",
* description="获取首页数量角标",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
@ -216,7 +217,7 @@ class OrdersController extends CommonController
/**
* @OA\Get(
* path="/manager/get-order/{id}",
* summary="获取订单详情",
* summary="V2-获取订单详情",
* description="获取订单详情",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"),
@ -406,7 +407,7 @@ class OrdersController extends CommonController
/**
* @OA\Get(
* path="/manager/get-paramedic/{id}",
* summary="获取护工详情",
* summary="V2-获取护工详情",
* description="获取护工详情",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"),
@ -420,11 +421,11 @@ class OrdersController extends CommonController
public function getParamedic($id)
{
$paramedic = (new Paramedic())->with([
"project" => function($query) {
$query->select("id","name","address");
"project" => function ($query) {
$query->select("id", "name", "address");
},
"level" => function($query) {
$query->select("id","name");
"level" => function ($query) {
$query->select("id", "name");
}
])->find($id);
return response()->json($paramedic ? $paramedic->toArray() : null);
@ -559,6 +560,51 @@ class OrdersController extends CommonController
}
}
/**
* @OA\Get(
* path="/manager/scan-pay/{order_id}",
* summary="V2-扫用户支付码收款",
* description="扫用户支付码收款",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Parameter(name="order_id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"),
* @OA\Parameter(name="money", in="query", @OA\Schema(type="number"), required=true, description="支付金额"),
* @OA\Parameter(name="auth_code", in="query", @OA\Schema(type="string"), required=true, description="扫码后获取的支付码"),
* @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=true, description="支付方式weixin,alipay"),
* @OA\Response(
* response="200",
* description="扫用户支付码收款"
* )
* )
*/
public function scanPay($order_id)
{
$order = (new Orders())->find($order_id);
$recharge = (new Recharge())->create([
"customer_id" => $order->customer->id,
"money" => request()->money,
"order_id" => $order->id,
"payment" => request()->type
]);
$recharge = $recharge->getSerial();
switch (request()->type) {
case "weixin":
try {
$res = (new WxMicroPay())->pay($recharge);
return response()->json([
"errorcode" => 0,
"errormsg" => "支付成功!"
]);
} catch (\Exception $exception) {
return response()->json([
"errorcode" => 60003,
"errormsg" => $exception->getMessage()
]);
}
break;
}
}
/**
* @OA\POST(
* path="/manager/confirm-order/{id}",

@ -0,0 +1,85 @@
<?php
namespace App\Libs;
use Exception;
use App\Models\Recharge;
class WxMicroPay extends WxPayCommon
{
public $pay_url = "https://api.mch.weixin.qq.com/pay/micropay";
function checkParameters()
{
if (!$this->parameters["out_trade_no"]) {
throw new Exception("缺少必填参数out_trade_no" . "<br>");
} elseif (!$this->parameters["body"]) {
throw new Exception("缺少必填参数body" . "<br>");
} elseif (!$this->parameters["total_fee"]) {
throw new Exception("缺少必填参数total_fee" . "<br>");
} elseif (!$this->parameters["auth_code"]) {
throw new Exception("缺少必填参数auth_code" . "<br>");
}
}
/**
*
* 扫码支付,并且确认结果,接口比较慢
* @param $recharge
*/
public function pay(Recharge $recharge)
{
//提交被扫支付
$this->setParameter("out_trade_no", $recharge->serial);
$this->setParameter("body", "充值{$recharge->money}元");
$this->setParameter("total_fee", $recharge->money * 100);
$this->setParameter("auth_code", request()->auth_code);
$this->checkParameters();
$xml = $this->createXml();
$result = $this->postXmlCurl($xml, $this->pay_url);
$result = $this->xmlToArray($result);
//如果返回成功
if (!array_key_exists("return_code", $result) || !array_key_exists("result_code", $result)) {
throw new Exception("接口调用失败");
}
return true;
//取订单号
$out_trade_no = $microPayInput->GetOut_trade_no();
//②、接口调用成功,明确返回调用失败
if ($result["return_code"] == "SUCCESS" &&
$result["result_code"] == "FAIL" &&
$result["err_code"] != "USERPAYING" &&
$result["err_code"] != "SYSTEMERROR") {
return false;
}
//③、确认支付是否成功
$queryTimes = 10;
while ($queryTimes > 0) {
$succResult = 0;
$queryResult = $this->query($out_trade_no, $succResult);
//如果需要等待1s后继续
if ($succResult == 2) {
sleep(2);
continue;
} else if ($succResult == 1) {//查询成功
return $queryResult;
} else {//订单交易失败
break;
}
}
//④、次确认失败,则撤销订单
if (!$this->cancel($out_trade_no)) {
throw new WxpayException("撤销单失败!");
}
return false;
}
}

@ -0,0 +1,263 @@
<?php
namespace App\Libs;
use Exception;
class WxPayCommon
{
public $app_id;
public $key;
public $merchant_id;
public $ssl_cert_path;
public $ssl_key_path;
public $parameters = [];
public function __construct()
{
$this->app_id = env("WEIXINPAY_APPID");
$this->key = env("WEIXINPAY_KEY");
$this->merchant_id = env("WEIXINPAY_MCHID");
$this->ssl_cert_path = env("WEIXINPAY_SSLCERT_PATH");
$this->ssl_key_path = env("WEIXINPAY_KEY_PATH");
}
function trimString($value)
{
$ret = null;
if (null != $value) {
$ret = $value;
if (strlen($ret) == 0) {
$ret = null;
}
}
return $ret;
}
/**
* 作用:设置请求参数
*/
function setParameter($parameter, $parameterValue)
{
$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}
function checkParameters()
{
//检测必填参数
}
/**
* 生成接口参数xml
*/
function createXml()
{
try {
$this->parameters["appid"] = $this->app_id;//公众账号ID
$this->parameters["mch_id"] = $this->merchant_id;//商户号
$this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip
$this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//签名
return $this->arrayToXml($this->parameters);
} catch (Exception $e) {
dd($e->getMessage());
}
}
/**
* 作用产生随机字符串不长于32位
*/
public function createNoncestr($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 getSign($Obj)
{
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//echo '【string1】'.$String.'</br>';
//签名步骤二在string后加入KEY
$String = $String . "&key=" . $this->key;
//echo "【string2】".$String."</br>";
//签名步骤三MD5加密
$String = md5($String);
//echo "【string3】 ".$String."</br>";
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
//echo "【result】 ".$result_."</br>";
return $result_;
}
/**
* 作用:格式化参数,签名过程需要使用
*/
function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar = "";
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
/**
* 作用array转xml
*/
function arrayToXml($arr)
{
$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;
}
/**
* 作用将xml转为array
*/
public function xmlToArray($xml)
{
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}
/**
* 作用以post方式提交xml到对应的接口url
*/
public function postXmlCurl($xml, $url, $second = 30)
{
//初始化curl
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//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);
echo "curl出错错误码:$error" . "<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($ch);
return false;
}
}
/**
* 作用使用证书以post方式提交xml到对应的接口url
*/
function postXmlSSLCurl($xml, $url, $second = 30)
{
$ch = curl_init();
//超时时间
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//设置证书
//使用证书cert 与 key 分别属于两个.pem文件
//默认格式为PEM可以注释
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, WxPayConfPub::SSLCERT_PATH);
//默认格式为PEM可以注释
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, WxPayConfPub::SSLKEY_PATH);
//post提交方式
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "curl出错错误码:$error" . "<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($ch);
return false;
}
}
/**
*
* 查询订单WxPayOrderQuery中out_trade_no、transaction_id至少填一个
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayConfigInterface $config 配置对象
* @param WxPayOrderQuery $inputObj
* @param int $timeOut
* @return 成功时返回,其他抛异常
* @throws WxPayException
*/
protected function orderQuery($config, $inputObj, $timeOut = 6)
{
$url = "https://api.mch.weixin.qq.com/pay/orderquery";
//检测必填参数
if (!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {
throw new WxPayException("订单查询接口中out_trade_no、transaction_id至少填一个");
}
$inputObj->SetAppid($config->GetAppId());//公众账号ID
$inputObj->SetMch_id($config->GetMerchantId());//商户号
$inputObj->SetNonce_str(self::getNonceStr());//随机字符串
$inputObj->SetSign($config);//签名
$xml = $inputObj->ToXml();
$startTimeStamp = self::getMillisecond();//请求开始时间
$response = self::postXmlCurl($config, $xml, $url, false, $timeOut);
$result = WxPayResults::Init($config, $response);
self::reportCostTime($config, $url, $startTimeStamp, $result);//上报请求花费时间
return $result;
}
}
Loading…
Cancel
Save