|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace App\Service;
|
|
|
|
|
|
|
|
use App\Exception\BusinessException;
|
|
|
|
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';
|
|
|
|
}
|
|
|
|
|
|
|
|
$order = Order::where('order_no', $params['out_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'] ?: 0;
|
|
|
|
$order->cny_amount = $params['cny_amount'] ?: 0;
|
|
|
|
if (!$order->save()) {
|
|
|
|
return 'NOTIFY FAIL';
|
|
|
|
}
|
|
|
|
|
|
|
|
Log::info('notifyToOut url:' . $order->notify_url, 'omipay');
|
|
|
|
$result = Notification::post($order->notify_url, $this->buildNotifyParams($order, $app));
|
|
|
|
if ($result != 'SUCCESS') {
|
|
|
|
return 'NOTIFY FAIL';
|
|
|
|
}
|
|
|
|
return 'SUCCESS';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildNotifyParams(Order $roder, App $app) {
|
|
|
|
$params = [
|
|
|
|
'app_id' => $order->app_id,
|
|
|
|
'nonce_str' => StringHelper::getRandomString(32),
|
|
|
|
'timestamp' => time(),
|
|
|
|
];
|
|
|
|
$bizData = [
|
|
|
|
'code' => 'SUCCESS',
|
|
|
|
'order_no' => $roder->order_no,
|
|
|
|
'out_order_no' => $roder->out_order_no,
|
|
|
|
'currency' => $roder->currency,
|
|
|
|
'total_amount' => $roder->amount,
|
|
|
|
'order_time' => date('YmdHis', strtotime($roder->created_at)),
|
|
|
|
'pay_time' => date('YmdHis', strtotime($roder->payed_at)),
|
|
|
|
'exchange_rate' => $roder->exchange_rate,
|
|
|
|
'cny_amount' => $roder->cny_amount,
|
|
|
|
];
|
|
|
|
$params['data'] = json_encode($bizData);
|
|
|
|
$params['sign'] = PlatformSigner::sign($params, $app->app_key);
|
|
|
|
|
|
|
|
Log::info('notifyToOut params:', $params, 'omipay');
|
|
|
|
|
|
|
|
return $params;
|
|
|
|
}
|
|
|
|
}
|