You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.8 KiB
PHP
172 lines
5.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Exception\BusinessException;
|
|
use App\Helper\Efps\PayNotify;
|
|
use App\Helper\Log;
|
|
use App\Helper\OmiPay\Api;
|
|
use App\Helper\OmiPay\Result;
|
|
use App\Helper\OmiPay\Signer;
|
|
use App\Helper\Platform\Notification;
|
|
use App\Helper\Platform\Signer as PlatformSigner;
|
|
use App\Helper\Redis;
|
|
use App\Helper\RedisKey;
|
|
use App\Helper\StringHelper;
|
|
use App\Model\App;
|
|
use App\Model\Order;
|
|
|
|
class PaymentService extends AbstractService
|
|
{
|
|
public function createOrder(App $app, array $params) {
|
|
$order = new Order();
|
|
$order->merchant_id = $app->merchant_id;
|
|
$order->app_id = $app->app_id;
|
|
$order->order_no = $this->generateOrderNo();
|
|
$order->out_order_no = $params['out_order_no'];
|
|
$order->order_name = $params['order_name'];
|
|
$order->amount = $params['amount'];
|
|
$order->currency = $params['currency'];
|
|
$order->redirect_url = $params['redirect_url'];
|
|
$order->notify_url = $params['notify_url'];
|
|
$order->direct_pay = $params['direct_pay'] ?? 0;
|
|
$order->show_pc_pay_url = $params['show_pc_pay_url'] ?? 0;
|
|
$order->o_number = $params['o_number'] ?? '';
|
|
$order->pos_no = $params['pos_no'] ?? '';
|
|
$order->status = Order::STATUS_PREPARE;
|
|
$order->save();
|
|
return $order;
|
|
}
|
|
|
|
private function generateOrderNo() {
|
|
$now = time();
|
|
$key = RedisKey::getGenerateOrderNoKey($now);
|
|
$incrId = Redis::incr($key);
|
|
$incrId = '' . $incrId;
|
|
Redis::expire($key, 5*60);
|
|
$padLength = 6 - strlen($incrId);
|
|
$incrId = str_pad($incrId, $padLength, '0', STR_PAD_LEFT);
|
|
return date('YmdHis', $now) . $incrId;
|
|
}
|
|
|
|
public function updateOrderResult(Order $order, Result $result) {
|
|
if ($result->isSuccess()) {
|
|
$order->pay_order_no = $result->get('order_no');
|
|
$order->pay_url = $result->get('pay_url');
|
|
$order->status = Order::STATUS_WAIT_PAY;
|
|
} else {
|
|
$order->error_code = $result->get('error_code');
|
|
$order->error_msg = $result->get('error_msg');
|
|
$order->status = Order::STATUS_FAILED;
|
|
}
|
|
$order->save();
|
|
}
|
|
|
|
public function jsapiPay(App $app, array $params) {
|
|
$order = Order::where('app_id', $app->app_id)->where('out_order_no', $params['out_order_no'])->first();
|
|
if ($order) {
|
|
throw new BusinessException('订单重复');
|
|
}
|
|
$order = $this->createOrder($app, $params);
|
|
$result = Api::getExchangeRate('AUD', 'CNY');
|
|
if (!$result->isSuccess()) {
|
|
throw new BusinessException('获取汇率接口失败');
|
|
}
|
|
$rate = $result->get('rate');
|
|
$result = Api::makeJSAPIOrder(
|
|
$order->order_name,
|
|
$order->order_no,
|
|
'AUD',
|
|
intval($order->amount / $rate),
|
|
'http://146.70.113.165:9501/payment/notify',
|
|
'http://146.70.113.165:9501/payment/page?order_no=' . $order->order_no
|
|
);
|
|
$this->updateOrderResult($order, $result);
|
|
return $order;
|
|
}
|
|
|
|
public function notify($params) {
|
|
Log::info('notify:', $params, 'omipay');
|
|
if (!Signer::verify($params)) {
|
|
return 'SIGN FAIL';
|
|
}
|
|
if ($params['return_code'] != 'SUCCESS') {
|
|
return 'STATUS FAIL';
|
|
}
|
|
$params = [
|
|
'order_no' => $params['out_order_no'],
|
|
'cny_amount' => $params['cny_amount'],
|
|
'exchange_rage' => $params['exchange_rage'],
|
|
];
|
|
return $this->handleNotify($params);
|
|
}
|
|
|
|
public function efpsNotify($params) {
|
|
Log::info('notify:', $params, 'omipay');
|
|
if (!Signer::verify($params)) {
|
|
return 'SIGN FAIL';
|
|
}
|
|
if ($params['return_code'] != 'SUCCESS') {
|
|
return 'STATUS FAIL';
|
|
}
|
|
$params = [
|
|
'order_no' => $params['outTradeNo'],
|
|
|
|
];
|
|
return $this->handleNotify($params);
|
|
}
|
|
|
|
private function handleNotify($params) {
|
|
$order = Order::where('order_no', $params['order_no'] ?: '')
|
|
->where('status', Order::STATUS_WAIT_PAY)
|
|
->first();
|
|
if (!$order) {
|
|
return 'ORDER FAIL';
|
|
}
|
|
$app = App::where('app_id', $order->app_id)->first();
|
|
$order->status = Order::STATUS_PAYED;
|
|
$order->payed_at = date('Y-m-d H:i:s');
|
|
$order->exchange_rate = $params['exchange_rate'] ?: 1;
|
|
$order->cny_amount = $params['cny_amount'] ?: $order->amount;
|
|
if (!$order->save()) {
|
|
return 'NOTIFY FAIL';
|
|
}
|
|
|
|
Log::info('notifyToOut url:' . $order->notify_url, [], 'omipay');
|
|
$result = Notification::post($order->notify_url, $this->buildNotifyParams($order, $app));
|
|
Log::info('notifyToOut response:' . $result, [], 'omipay');
|
|
if ($result != 'SUCCESS') {
|
|
return 'NOTIFY FAIL';
|
|
}
|
|
return 'SUCCESS';
|
|
}
|
|
|
|
protected function buildNotifyParams(Order $order, App $app) {
|
|
$params = [
|
|
'app_id' => $order->app_id,
|
|
'nonce_str' => StringHelper::getRandomString(32),
|
|
'timestamp' => time(),
|
|
];
|
|
$bizData = [
|
|
'code' => 'SUCCESS',
|
|
'order_no' => $order->order_no,
|
|
'out_order_no' => $order->out_order_no,
|
|
'currency' => $order->currency,
|
|
'total_amount' => $order->amount,
|
|
'order_time' => date('YmdHis', $order->created_at->timestamp),
|
|
'pay_time' => date('YmdHis', strtotime($order->payed_at)),
|
|
'exchange_rate' => $order->exchange_rate,
|
|
'cny_amount' => $order->cny_amount,
|
|
];
|
|
$params['data'] = json_encode($bizData);
|
|
$params['sign'] = PlatformSigner::sign($params, $app->app_key);
|
|
|
|
Log::info('notifyToOut params:', $params, 'omipay');
|
|
|
|
return $params;
|
|
}
|
|
|
|
}
|