253 lines
8.3 KiB
PHP
253 lines
8.3 KiB
PHP
<?php
|
||
/**
|
||
* Created by PhpStorm.
|
||
* User: Administrator
|
||
* Date: 2020/4/17
|
||
* Time: 21:07
|
||
*/
|
||
|
||
namespace app\api\service;
|
||
use app\api\model\Order as OrderModel;
|
||
use app\api\service\Order as OrderService;
|
||
use app\lib\exception\ParamException;
|
||
use \think\facade\Log;
|
||
|
||
|
||
require '../extend/WxPay/WxPay.Api.php';
|
||
|
||
class Pay
|
||
{
|
||
|
||
private $orderNo;
|
||
private $payWay;
|
||
private $payType;
|
||
private $orderID;
|
||
function __construct($orderID,$payType,$payWay)
|
||
{
|
||
if (!$orderID)
|
||
{
|
||
throw new Exception('订单号不允许为NULL');
|
||
}
|
||
$this->orderID = $orderID;
|
||
$this->payType = $payType;
|
||
$this->payWay = $payWay;
|
||
}
|
||
|
||
|
||
//微信H5支付
|
||
public function wapPay($user_id,$rebackUrl){
|
||
$resOrder = $this->checkOrderValid( $this->orderID,$user_id);
|
||
//调用统一下单接口
|
||
$wxOrderData = new \WxPayUnifiedOrder();
|
||
$wxOrderData->SetOut_trade_no( $resOrder['ord_no']);
|
||
$wxOrderData->SetTrade_type('MWEB');
|
||
$wxOrderData->SetTotal_fee($resOrder['money']*100);
|
||
$wxOrderData->setBody('聚志愿');
|
||
$wxOrderData->SetNotify_url(config('secure.pay_back_url'));
|
||
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
|
||
$url = $wxOrder['mweb_url'].'&redirect_url='.$rebackUrl;//redirect_url 是支付完成后返回的页面
|
||
return $url;
|
||
}
|
||
|
||
|
||
|
||
//微信扫码支付
|
||
public function codePay($user_id){
|
||
//
|
||
$resOrder = $this->checkOrderValid( $this->orderID,$user_id);
|
||
//调用统一下单接口
|
||
$wxOrderData = new \WxPayUnifiedOrder();
|
||
$wxOrderData->SetOut_trade_no($resOrder['ord_no']);
|
||
$wxOrderData->SetTrade_type('NATIVE');
|
||
$wxOrderData->SetTime_start(date("YmdHis"));
|
||
$wxOrderData->SetTime_expire(date("YmdHis", time() + 600));
|
||
$wxOrderData->SetProduct_id($resOrder['vip']);
|
||
$wxOrderData->SetTotal_fee($resOrder['money']*100);
|
||
$wxOrderData->setBody('聚志愿');
|
||
$wxOrderData->SetNotify_url(config('secure.pay_back_url'));
|
||
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
|
||
if($wxOrder['result_code']=='SUCCESS' && $wxOrder['return_code']=='SUCCESS') {
|
||
$url = $wxOrder["code_url"];
|
||
return $url;
|
||
}else{
|
||
throw new ParamException([
|
||
'msg' => '参数错误',
|
||
'errorCode' => 10000,
|
||
'code' => 400
|
||
]);
|
||
|
||
}
|
||
}
|
||
|
||
|
||
//支付宝wap支付
|
||
public function alipay_wap($user_id,$rebackUrl)
|
||
{
|
||
|
||
$resOrder = $this->checkOrderValid( $this->orderID,$user_id);
|
||
require '../extend/alipay/aop/AopClient.php';// 加载交易服务
|
||
//商品参数
|
||
$array['body'] = "聚志愿";
|
||
$array['subject'] = "聚志愿vip权限";
|
||
$array['out_trade_no'] = $resOrder['ord_no'];
|
||
$array['timeout_express'] = "5m";
|
||
$array['total_amount'] = $resOrder['money'];
|
||
$array['product_code'] = "QUICK_WAP_WAY";
|
||
|
||
$aop = new \AopClient ();
|
||
//支付配置参数
|
||
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
|
||
$aop->appId = config('alipay.app_id');
|
||
$aop->rsaPrivateKey = config('alipay.merchant_private_key');
|
||
$aop->alipayrsaPublicKey=config('alipay.alipay_public_key');
|
||
$aop->signType='RSA2';
|
||
$aop->format = "json";
|
||
|
||
require '../extend/alipay/aop/request/AlipayTradeWapPayRequest.php';// 加载交易服务
|
||
$request = new \AlipayTradeWapPayRequest ();
|
||
|
||
$request->setBizContent(json_encode($array));
|
||
//回调地址
|
||
$request->setReturnUrl($rebackUrl);
|
||
$request->setNotifyUrl(config('alipay.notify_url'));
|
||
$result = $aop->pageExecute($request, "POST");
|
||
return $result;
|
||
}
|
||
|
||
|
||
//支付宝pc支付
|
||
public function alipay_pc($user_id,$rebackUrl)
|
||
{
|
||
$resOrder = $this->checkOrderValid( $this->orderID,$user_id);
|
||
require '../extend/alipaypage/pagepay/service/AlipayTradeService.php';// 加载交易服务
|
||
require '../extend/alipaypage/pagepay/buildermodel/AlipayTradePagePayContentBuilder.php';
|
||
//商品参数
|
||
$body = "聚志愿";
|
||
$subject = "聚志愿vip权限";
|
||
$out_trade_no= $resOrder['ord_no'];
|
||
$timeout_express = "5m";
|
||
$total_amount = $resOrder['money'];
|
||
|
||
|
||
$payRequestBuilder = new \AlipayTradePagePayContentBuilder();
|
||
$payRequestBuilder->setBody($body);
|
||
$payRequestBuilder->setSubject($subject);
|
||
$payRequestBuilder->setTotalAmount($total_amount);
|
||
$payRequestBuilder->setOutTradeNo($out_trade_no);
|
||
$payRequestBuilder->setTimeExpress($timeout_express);
|
||
|
||
$config = config('alipay.');
|
||
$aop = new \AlipayTradeService($config);
|
||
$result = $aop->pagePay($payRequestBuilder,$rebackUrl,$config['notify_url']);
|
||
|
||
return $result;
|
||
}
|
||
|
||
|
||
|
||
|
||
//小程序支付
|
||
public function pay()
|
||
{
|
||
// 订单号可能不存在
|
||
//订单号和用户不匹配
|
||
//订单可能倍支付过
|
||
//进行库存量检测
|
||
$this->checkOrderValid();
|
||
$orderService = new OrderService();
|
||
$status = $orderService->checkOrderStock($this->orderID);
|
||
if(!$status['pass']){
|
||
return $status;
|
||
}
|
||
return $this->makeWxPreOrder($status['orderPrice']);
|
||
}
|
||
// 构建微信支付订单信息
|
||
private function makeWxPreOrder($totalPrice){
|
||
$openid = Token::getCurrentTokenVar('openid');
|
||
if(!$openid){
|
||
throw new TokenException();
|
||
}
|
||
//调用统一下单接口
|
||
$wxOrderData = new \WxPayUnifiedOrder();
|
||
$wxOrderData->SetOut_trade_no($this->orderNo);
|
||
$wxOrderData->SetTrade_type('JSAPI');
|
||
$wxOrderData->SetTotal_fee($totalPrice*100);
|
||
$wxOrderData->setBody('伊莎商城');
|
||
$wxOrderData->SetOpenid($openid);
|
||
$wxOrderData->SetNotify_url(config('secure.pay_back_url'));
|
||
return $this->getPaySignature($wxOrderData);
|
||
}
|
||
//向微信请求订单号并生成签名
|
||
private function getPaySignature($wxOrderData){
|
||
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
|
||
// 失败时不会返回result_code
|
||
if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
|
||
Log::record($wxOrder,'error');
|
||
Log::record('获取预支付订单失败','error');
|
||
|
||
}
|
||
|
||
$this->recordPreOrder($wxOrder);
|
||
$signature = $this->sign($wxOrder);
|
||
return $signature;
|
||
}
|
||
|
||
private function sign($wxOrder){
|
||
$jsApiPayData = new \WxPayJsApiPay();
|
||
$jsApiPayData->SetAppid(config('wx.app_id'));
|
||
$jsApiPayData->SetTimeStamp((string)time());
|
||
$rand = md5(time() . mt_rand(0, 1000));
|
||
$jsApiPayData->SetNonceStr($rand);
|
||
$jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
|
||
$jsApiPayData->SetSignType('md5');
|
||
$sign = $jsApiPayData->MakeSign();
|
||
$rawValues = $jsApiPayData->GetValues();
|
||
$rawValues['paySign'] = $sign;
|
||
unset($rawValues['appId']);
|
||
return $rawValues;
|
||
}
|
||
|
||
private function recordPreOrder($wxOrder){
|
||
// 必须是update,每次用户取消支付后再次对同一订单支付,prepay_id是不同的
|
||
OrderModel::where('id', '=', $this->orderID)
|
||
->update(['prepay_id' => $wxOrder['prepay_id']]);
|
||
}
|
||
|
||
/**
|
||
* 订单验证
|
||
* @return string
|
||
* @throws OrderException
|
||
* @throws TokenException
|
||
*/
|
||
private function checkOrderValid($orderTD,$userID){
|
||
$order = OrderModel::field('id,ord_no,status,money,vip')->where([['id','=',$orderTD],['user_id','=',$userID]])
|
||
->find();
|
||
|
||
if(!$order){
|
||
throw new ParamException([
|
||
'msg' => '订单不存在',
|
||
'errorCode' => 10004,
|
||
'code' => 404
|
||
]);
|
||
}
|
||
if(!Token::isValidOperate($userID)){
|
||
throw new ParamException([
|
||
'msg' => '订单与用户信息不匹配',
|
||
'errorCode' => 10000,
|
||
'code' => 400
|
||
]);
|
||
}
|
||
|
||
if($order['status'] == 1){
|
||
throw new ParamException([
|
||
'msg' => '订单已支付过啦',
|
||
'errorCode' => 10000,
|
||
'code' => 400
|
||
]);
|
||
}
|
||
|
||
return $order;
|
||
|
||
}
|
||
|
||
} |