| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- <?php
- namespace App\Http\logic\api;
- use App\dao\Pay\AccountPayInfo;
- use App\dao\Pay\PayController;
- use App\Http\helper\CreateOrder;
- use App\Http\helper\NumConfig;
- use App\Jobs\Order;
- use App\Notification\TelegramBot;
- use App\Services\CreateLog;
- use App\Services\OrderServices;
- use App\Services\PayConfig;
- use App\Services\PayPlus;
- use App\Util;
- use Illuminate\Support\Facades\DB;
- class PayPlusLogic extends BaseApiLogic
- {
- protected $service;
- public function __construct(PayPlus $service = null)
- {
- $this->service = $service ?: new PayPlus();
- }
- public function pay_order(
- $userId,
- $payAmount,
- $userPhone,
- $userEmail,
- $userName,
- $GiftsID,
- $buyIP,
- $AdId,
- $eventType,
- $payMethod = ''
- ) {
- $dao = new AccountPayInfo();
- list($userPhone, $userName, $userEmail) = $dao->payInfo($userId);
- $payVerify = new PayController();
- $payAmount = $payVerify->verify($userId, $GiftsID, $payAmount);
- if ($payAmount === false || $payAmount < 0) {
- $this->error = $payVerify->getError() ?: 'Payment error_4';
- return false;
- }
- $orderSn = CreateOrder::order_sn($userId);
- $amount = (int) round($payAmount * NumConfig::NUM_VALUE);
- $logic = new OrderLogic();
- if (
- !$logic->orderCreate(
- $orderSn,
- $amount,
- 'PayPlus',
- $userId,
- $payMethod,
- $GiftsID,
- $AdId,
- $eventType
- )
- ) {
- $this->error = $logic->getError();
- return false;
- }
- $payload = $this->buildPaymentPayload([
- 'order_sn' => $orderSn,
- 'amount' => $payAmount,
- 'user_id' => $userId,
- 'user_email' => $userEmail,
- 'user_phone' => $userPhone,
- 'user_name' => $userName,
- 'buy_ip' => $buyIP,
- 'pay_method' => $payMethod,
- ]);
- CreateLog::pay_request(
- $userPhone,
- json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
- $orderSn,
- $userEmail,
- $userId,
- $userName
- );
- Util::WriteLog('PayPlus', 'PayPlus payment request: ' . json_encode($payload));
- try {
- $result = $this->service->postPayin($payload);
- Util::WriteLog('PayPlus', 'PayPlus payment response: ' . json_encode($result));
- if ($result['code'] !== 200) {
- TelegramBot::getDefault()->sendProgramNotify(
- 'PayPlus payment failed',
- 'Response: ' . json_encode($result),
- null
- );
- }
- return $result;
-
- } catch (\Exception $exception) {
- Util::WriteLog('PayPlus_error', $exception->getMessage());
- $this->error = 'Payment processing error';
- return false;
- }
- }
- public function buildPaymentPayload(array $input)
- {
- $config = $this->service->getConfig();
- $payMethod = (int) ($input['pay_method'] ?: 1);
- $methodMap = $config['payment_methods'] ?? [
- 1 => 8,
- 2 => 2,
- 4 => 1,
- 8 => 5,
- ];
- $nameParts = preg_split('/\s+/', trim((string) ($input['user_name'] ?? '')), 2);
- return [
- 'order_type' => 'RECHARGE',
- 'platform_order_id' => (string) $input['order_sn'],
- 'currency' => strtoupper($config['currency'] ?? 'USD'),
- 'amount' => number_format((float) $input['amount'], 2, '.', ''),
- 'payment_method' => $methodMap[$payMethod] ?? 8,
- 'return_url' => $config['return'] ?? '',
- 'cancel_url' => $config['cancel'] ?? ($config['return'] ?? ''),
- 'connection_info' => [
- 'ip' => $input['buy_ip'] ?: '0.0.0.0',
- 'country' => $config['country'] ?? 'US',
- 'state' => $config['state'] ?? 'NY',
- 'zip_code' => $config['zip'] ?? '00000',
- 'media_source' => $config['media_source'] ?? 'organic',
- 'language' => $config['language'] ?? 'en-US',
- ],
- 'account_info' => [
- 'merchant_user_id' => (string) $input['user_id'],
- 'create_time' => time()*1000,
- 'role' => 'PRIVATE',
- 'email' => $this->emailOrDefault($input['user_email'] ?? '', $input['user_id']),
- 'phone' => preg_replace('/\D+/', '', (string) ($input['user_phone'] ?? '')) ?: '0000000000',
- 'area_code' => $config['area_code'] ?? '1',
- 'first_name' => chr(mt_rand(65, 90)) . 'user',
- 'last_name' => chr(mt_rand(65, 90)) . 'user',
- 'vip_level' => 0,
- ],
- ];
- }
- public function notify(array $post)
- {
- $orderSn = $post['data']['platform_order_id'] ?? '';
- if ($orderSn === '') {
- return 'success';
- }
- $order = DB::connection('write')
- ->table('agent.dbo.order')
- ->where('order_sn', $orderSn)
- ->first();
- if (!$order || !empty($order->pay_at) || !empty($order->finished_at)) {
- return 'success';
- }
- $data = $post['data'] ?? [];
- $body = [
- 'payment_sn' => $data['order_id'] ?? '',
- 'updated_at' => date('Y-m-d H:i:s'),
- ];
- if ($this->isSuccessfulPayment($post)) {
- if (!$this->confirmSuccessfulPayment($post)) {
- Util::WriteLog('PayPlus', 'PayPlus order query not successful: ' . json_encode($post));
- return 'success';
- }
- $AdId = $order->AdId ?: '';
- $eventType = $order->eventType ?: '';
- $payAmount = round((float) ($data['amount'] ?? 0), 2);
- $body['pay_status'] = 1;
- $body['pay_at'] = date('Y-m-d H:i:s');
- $body['finished_at'] = date('Y-m-d H:i:s');
- $body['amount'] = (int) round($payAmount * NumConfig::NUM_VALUE);
- $config = (new PayConfig())->getConfig('PayPlus');
- // 根据支付方式计算代收手续费: 费率% * 金额 + 固定$
- // pay_rate 格式: [1=>[10,0.3], 2=>[13,0.3], 4=>[11,0.3], 8=>[12,0.3]]
- $payRates = $config['pay_rate'] ?? null;
- if (is_array($payRates)) {
- $payMethod = $order->order_title ?? 1;
- $payRate = $payRates[$payMethod] ?? ($payRates[1] ?? [10, 0.3]);
- $feePercent = $payRate[0] ?? 10;
- $feeFixed = $payRate[1] ?? 0.3;
- $body['payment_fee'] = intval(($body['amount'] * $feePercent) / 100)
- + (int)($feeFixed * NumConfig::NUM_VALUE);
- }
- $service = new OrderServices();
- list($give, $favorablePrice, $recharge, $czReason, $cjReason) = $service->getPayInfo(
- $order->GiftsID ?: '',
- $order->user_id ?: '',
- $payAmount
- );
- list($score) = $service->addRecord(
- $order->user_id,
- $payAmount,
- $favorablePrice,
- $orderSn,
- $order->GiftsID,
- $recharge,
- $czReason,
- $give,
- $cjReason,
- $order->AdId ?: '',
- $order->eventType ?: '',
- $body['payment_fee'] ?? 0
- );
- Order::dispatch([
- $order->user_id,
- $payAmount,
- $score,
- $favorablePrice,
- $order->GiftsID,
- $orderSn,
- ]);
- } else {
- return 'success';
- }
- DB::connection('write')
- ->table('agent.dbo.order')
- ->where('order_sn', $orderSn)
- ->update($body);
- return 'success';
- }
- public function isSuccessfulPayment(array $post)
- {
- return ($post['event'] ?? '') === 'PAYMENT.CAPTURE.COMPLETED'
- && ($post['event_detail_name'] ?? '') === 'payment_captured'
- && (int) ($post['data']['order_status'] ?? 0) === 3;
- }
- public function confirmSuccessfulPayment(array $post)
- {
- $data = $post['data'] ?? [];
- $platformOrderId = $data['platform_order_id'] ?? '';
- if ($platformOrderId === '') {
- return false;
- }
- try {
- $result = $this->service->queryPayinOrder($platformOrderId, $data['order_id'] ?? '');
- } catch (\Exception $exception) {
- Util::WriteLog('PayPlus_error', 'PayPlus query order failed: ' . $exception->getMessage());
- return false;
- }
- return $this->isSuccessfulPaymentQueryResult($result);
- }
- public function isSuccessfulPaymentQueryResult(array $result)
- {
- $data = $result['decryptedComponentDelta'] ?? ($result['data'] ?? $result);
- return (int) ($data['order_status'] ?? 0) === 3;
- }
- public function isFailedPayment(array $post)
- {
- $event = $post['event'] ?? '';
- $detail = $post['event_detail_name'] ?? '';
- $status = (int) ($post['data']['order_status'] ?? 0);
- return ($event === 'PAYMENT.CAPTURE.COMPLETED' && in_array($status, [4, 10, 11], true))
- || $event === 'PAYMENT.ORDER.TIMEOUT'
- || in_array($detail, ['payment_declined', 'payment_timeout'], true);
- }
- protected function resolvePaymentUrl(array $result)
- {
- $data = $result['data'] ?? $result;
- foreach (['cashierUrl', 'cashier_url', 'payment_url', 'paymentUrl', 'redirect_url', 'url'] as $key) {
- if (!empty($data[$key])) {
- return $data[$key];
- }
- }
- return '';
- }
- protected function emailOrDefault($email, $userId)
- {
- return filter_var($email, FILTER_VALIDATE_EMAIL) ? $email : 'unknown' . $userId . '@example.com';
- }
- protected function stringOrDefault($value, $default)
- {
- $value = trim((string) $value);
- return $value === '' ? $default : $value;
- }
- }
|