首先找個(gè)簡(jiǎn)單好用的輪子 比如這個(gè)https://github.com/latrell/Alipay
這個(gè)輪子有一個(gè)地方有毒,就是只有支付,沒(méi)有退款之類的接口!我公司比較屌,付錢(qián)了就沒(méi)退款這一說(shuō),我就用了!不過(guò)我主要講訂單生成這塊
首先創(chuàng)建一個(gè)中間件 php artisan make:middleware IsMobile
這個(gè)中間件主要功能是判斷請(qǐng)求進(jìn)來(lái)的是手機(jī)還是電腦端 調(diào)用方式
$payType = $isMobile? 'alipay.wap' : 'alipay.web';
<?php
namespace App\Http\Middleware;
use Closure;
class IsMobile
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$isMobile = $this->isMobile();
$request['isMobile'] = $isMobile;
return $next($request);
}
//判斷是否是移動(dòng)端訪問(wèn)
public function isMobile()
{
// 如果有HTTP_X_WAP_PROFILE則一定是移動(dòng)設(shè)備
if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])) {
return TRUE;
}
// 如果via信息含有wap則一定是移動(dòng)設(shè)備,部分服務(wù)商會(huì)屏蔽該信息
if (isset ($_SERVER['HTTP_VIA'])) {
return stristr($_SERVER['HTTP_VIA'], "wap") ? TRUE : FALSE;// 找不到為flase,否則為T(mén)RUE
}
// 判斷手機(jī)發(fā)送的客戶端標(biāo)志,兼容性有待提高
if (isset ($_SERVER['HTTP_USER_AGENT'])) {
$clientkeywords = array(
'mobile',
'nokia',
'sony',
'ericsson',
'mot',
'samsung',
'htc',
'sgh',
'lg',
'sharp',
'sie-',
'philips',
'panasonic',
'alcatel',
'lenovo',
'iphone',
'ipod',
'blackberry',
'meizu',
'android',
'netfront',
'symbian',
'ucweb',
'windowsce',
'palm',
'operamini',
'operamobi',
'openwave',
'nexusone',
'cldc',
'midp',
'wap'
);
// 從HTTP_USER_AGENT中查找手機(jī)瀏覽器的關(guān)鍵字
if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
return TRUE;
}
}
if (isset ($_SERVER['HTTP_ACCEPT'])) { // 協(xié)議法,因?yàn)橛锌赡懿粶?zhǔn)確,放到最后判斷
// 如果只支持wml并且不支持html那一定是移動(dòng)設(shè)備
// 如果支持wml和html但是wml在html之前則是移動(dòng)設(shè)備
if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== FALSE) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === FALSE || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
return TRUE;
}
}
return FALSE;
}
}
接下來(lái)創(chuàng)建本地訂單
主要是訂單ID這塊,想了很多方法,什么時(shí)間戳啊+用戶ID之類的啊,但是你都不能100%排除有一定幾率訂單號(hào)重復(fù)吧,如果并發(fā)量非常非常大的時(shí)候更恐怖,然后就有個(gè)大佬告訴我先生成訂單號(hào)放在另外一張數(shù)據(jù)表中,每次用的時(shí)候拿一個(gè),同時(shí)鎖表!這個(gè)ider真的是666
/**
* 批量生成訂單id,必須在php-cli下執(zhí)行
*
* 訂單號(hào)范圍:
* => 11000001 - 99999999
* =>
*
* @param $s
* @param $e
*/
public function makeTmpOrderIds($s = 1, $e = 2)
{
$total = $e - $s;
$pageSize = 30000;
$page = 1;
$pageCount = ceil($total / $pageSize);
$pageArr = [];
for ($i = $page; $i <= $pageCount; $i++) {
$pageArr[] = $i;
}
shuffle($pageArr);
foreach ($pageArr as $page) {
$orderIds = [];
$start = $s + ($page - 1) * $pageSize;
$end = $s + $page * $pageSize;
for ($j = $start; $j <= $end; $j++) {
$orderIds[] = $j;
}
shuffle($orderIds); //隨機(jī)
$this->muitlInsertOrderIds($orderIds);
sleep(1); //減輕sql壓力
}
}
/**
* 批量插入訂單id
*
* @param $orderIds
*/
public function muitlInsertOrderIds($orderIds)
{
$value_sql = '(?)' . str_repeat(',(?)', (count($orderIds) - 1));
$sql = "insert ignore into `small`.`small_order_ids` (`order_id`) values {$value_sql}";
DB::insert($sql, $orderIds);
}
命令調(diào)用填充數(shù)據(jù)表,生成命令的方式看下文檔就好
Artisan::command('make_order_ids', function () {
$obj = new \App\Emotion\Services\OrderService();
//$obj->makeTmpOrderIds(11000001, 99999999);
// $obj->makeTmpOrderIds(30000000, 40000000);
// $obj->makeTmpOrderIds(40000000, 50000000);
// $obj->makeTmpOrderIds(50000000, 60000000);
// $obj->makeTmpOrderIds(60000000, 60000000);
// $obj->makeTmpOrderIds(70000000, 80000000);
// $obj->makeTmpOrderIds(80000000, 90000000);
// $obj->makeTmpOrderIds(90000000, 100000000);
// $obj->makeTmpOrderIds(100000000, 110000000);
})->describe('test');
我相信當(dāng)你110000000用完的時(shí)候,你們公司就和淘寶一樣的規(guī)模了
接下來(lái)就是創(chuàng)建本地訂單了后調(diào)用支付寶啦。這塊很簡(jiǎn)單的直接上代碼,看不明白的留言或者直接加我QQ 1021081996,下班了,有機(jī)會(huì)再改這個(gè)文檔,我知道寫(xiě)的不好!
$isMobile = $request->input('isMobile');
$payType = $isMobile? 'alipay.wap' : 'alipay.web';
$is_test = 1;
// 創(chuàng)建測(cè)評(píng)服務(wù)本地訂單
$orderId = $order->makeAliOrder([
'total_price' => $productInfo['price'],
'question_id' => $questionId,
'is_test' => $is_test ? 1 : 0
]);
$orderInfo = AlipayOrder::where('order_id', $orderId)->orderBy('id', 'desc')->first();
$totalPrice = ceil($productInfo['price']/100); //問(wèn)題中按分存的,所以需要除 100
$totalPrice = $is_test == 1 ? 0.01 : $totalPrice;
// 發(fā)起支付寶支付
$alipay = app($payType);
$alipay->setOutTradeNo($orderId);//訂單id
$alipay->setTotalFee($totalPrice);//支付價(jià)格
$alipay->setSubject($productInfo['title']);//支付標(biāo)題
$alipay->setBody($productInfo['intro']);//支付詳情
//$alipay->setQrPayMode('3'); //該設(shè)置為可選,添加該參數(shù)設(shè)置,支持二維碼支付。
// 跳轉(zhuǎn)到支付頁(yè)面。
return redirect()->to($alipay->getPayLink());