PayPlusLogic.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. namespace App\Http\logic\api;
  3. use App\dao\Pay\AccountPayInfo;
  4. use App\dao\Pay\PayController;
  5. use App\Http\helper\CreateOrder;
  6. use App\Http\helper\NumConfig;
  7. use App\Jobs\Order;
  8. use App\Services\CreateLog;
  9. use App\Services\OrderServices;
  10. use App\Services\PayPlus;
  11. use App\Util;
  12. use Illuminate\Support\Facades\DB;
  13. class PayPlusLogic extends BaseApiLogic
  14. {
  15. protected $service;
  16. public function __construct(PayPlus $service = null)
  17. {
  18. $this->service = $service ?: new PayPlus();
  19. }
  20. public function pay_order(
  21. $userId,
  22. $payAmount,
  23. $userPhone,
  24. $userEmail,
  25. $userName,
  26. $GiftsID,
  27. $buyIP,
  28. $AdId,
  29. $eventType,
  30. $payMethod = ''
  31. ) {
  32. $dao = new AccountPayInfo();
  33. list($userPhone, $userName, $userEmail) = $dao->payInfo($userId);
  34. $payVerify = new PayController();
  35. $payAmount = $payVerify->verify($userId, $GiftsID, $payAmount);
  36. if ($payAmount === false || $payAmount < 0) {
  37. $this->error = $payVerify->getError() ?: 'Payment error_4';
  38. return false;
  39. }
  40. $orderSn = CreateOrder::order_sn($userId);
  41. $amount = (int) round($payAmount * NumConfig::NUM_VALUE);
  42. $logic = new OrderLogic();
  43. if (
  44. !$logic->orderCreate(
  45. $orderSn,
  46. $amount,
  47. 'PayPlus',
  48. $userId,
  49. $payMethod,
  50. $GiftsID,
  51. $AdId,
  52. $eventType
  53. )
  54. ) {
  55. $this->error = $logic->getError();
  56. return false;
  57. }
  58. $payload = $this->buildPaymentPayload([
  59. 'order_sn' => $orderSn,
  60. 'amount' => $payAmount,
  61. 'user_id' => $userId,
  62. 'user_email' => $userEmail,
  63. 'user_phone' => $userPhone,
  64. 'user_name' => $userName,
  65. 'buy_ip' => $buyIP,
  66. 'pay_method' => $payMethod,
  67. ]);
  68. CreateLog::pay_request(
  69. $userPhone,
  70. json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
  71. $orderSn,
  72. $userEmail,
  73. $userId,
  74. $userName
  75. );
  76. Util::WriteLog('PayPlus', 'PayPlus payment request: ' . json_encode($payload));
  77. try {
  78. $result = $this->service->postPayin($payload);
  79. Util::WriteLog('PayPlus', 'PayPlus payment response: ' . json_encode($result));
  80. return $result;
  81. } catch (\Exception $exception) {
  82. Util::WriteLog('PayPlus_error', $exception->getMessage());
  83. $this->error = 'Payment processing error';
  84. return false;
  85. }
  86. }
  87. public function buildPaymentPayload(array $input)
  88. {
  89. $config = $this->service->getConfig();
  90. $payMethod = (int) ($input['pay_method'] ?: 1);
  91. $methodMap = $config['payment_methods'] ?? [
  92. 1 => 8,
  93. 2 => 2,
  94. 4 => 1,
  95. 8 => 5,
  96. ];
  97. $nameParts = preg_split('/\s+/', trim((string) ($input['user_name'] ?? '')), 2);
  98. return [
  99. 'order_type' => 'RECHARGE',
  100. 'platform_order_id' => (string) $input['order_sn'],
  101. 'currency' => strtoupper($config['currency'] ?? 'USD'),
  102. 'amount' => number_format((float) $input['amount'], 2, '.', ''),
  103. 'payment_method' => $methodMap[$payMethod] ?? 8,
  104. 'return_url' => $config['return'] ?? '',
  105. 'cancel_url' => $config['cancel'] ?? ($config['return'] ?? ''),
  106. 'connection_info' => [
  107. 'ip' => $input['buy_ip'] ?: '0.0.0.0',
  108. 'country' => $config['country'] ?? 'US',
  109. 'state' => $config['state'] ?? 'NA',
  110. 'zip_code' => $config['zip'] ?? '00000',
  111. 'media_source' => $config['media_source'] ?? 'organic',
  112. 'language' => $config['language'] ?? 'en-US',
  113. ],
  114. 'account_info' => [
  115. 'merchant_user_id' => (string) $input['user_id'],
  116. 'create_time' => time()*1000,
  117. 'role' => 'PRIVATE',
  118. 'email' => $this->emailOrDefault($input['user_email'] ?? '', $input['user_id']),
  119. 'phone' => preg_replace('/\D+/', '', (string) ($input['user_phone'] ?? '')) ?: '0000000000',
  120. 'area_code' => $config['area_code'] ?? '1',
  121. 'first_name' => 'user',
  122. 'last_name' => 'user',
  123. 'vip_level' => 0,
  124. ],
  125. ];
  126. }
  127. public function notify(array $post)
  128. {
  129. $orderSn = $post['data']['platform_order_id'] ?? '';
  130. if ($orderSn === '') {
  131. return 'success';
  132. }
  133. $order = DB::connection('write')
  134. ->table('agent.dbo.order')
  135. ->where('order_sn', $orderSn)
  136. ->first();
  137. if (!$order || !empty($order->pay_at) || !empty($order->finished_at)) {
  138. return 'success';
  139. }
  140. $data = $post['data'] ?? [];
  141. $body = [
  142. 'payment_sn' => $data['order_id'] ?? '',
  143. 'updated_at' => date('Y-m-d H:i:s'),
  144. ];
  145. if ($this->isSuccessfulPayment($post)) {
  146. $payAmount = round((float) ($data['amount'] ?? 0), 2);
  147. $body['pay_status'] = 1;
  148. $body['pay_at'] = date('Y-m-d H:i:s');
  149. $body['finished_at'] = date('Y-m-d H:i:s');
  150. $body['amount'] = (int) round($payAmount * NumConfig::NUM_VALUE);
  151. $service = new OrderServices();
  152. list($give, $favorablePrice, $recharge, $czReason, $cjReason) = $service->getPayInfo(
  153. $order->GiftsID ?: '',
  154. $order->user_id ?: '',
  155. $payAmount
  156. );
  157. list($score) = $service->addRecord(
  158. $order->user_id,
  159. $payAmount,
  160. $favorablePrice,
  161. $orderSn,
  162. $order->GiftsID,
  163. $recharge,
  164. $czReason,
  165. $give,
  166. $cjReason,
  167. $order->AdId ?: '',
  168. $order->eventType ?: '',
  169. 0
  170. );
  171. Order::dispatch([
  172. $order->user_id,
  173. $payAmount,
  174. $score,
  175. $favorablePrice,
  176. $order->GiftsID,
  177. $orderSn,
  178. ]);
  179. } elseif ($this->isFailedPayment($post)) {
  180. $body['pay_status'] = 2;
  181. } else {
  182. return 'success';
  183. }
  184. DB::connection('write')
  185. ->table('agent.dbo.order')
  186. ->where('order_sn', $orderSn)
  187. ->update($body);
  188. return 'success';
  189. }
  190. public function isSuccessfulPayment(array $post)
  191. {
  192. return ($post['event'] ?? '') === 'PAYMENT.CAPTURE.COMPLETED'
  193. && ($post['event_detail_name'] ?? '') === 'payment_captured'
  194. && (int) ($post['data']['order_status'] ?? 0) === 3;
  195. }
  196. public function isFailedPayment(array $post)
  197. {
  198. $event = $post['event'] ?? '';
  199. $detail = $post['event_detail_name'] ?? '';
  200. $status = (int) ($post['data']['order_status'] ?? 0);
  201. return ($event === 'PAYMENT.CAPTURE.COMPLETED' && in_array($status, [4, 10, 11], true))
  202. || $event === 'PAYMENT.ORDER.TIMEOUT'
  203. || in_array($detail, ['payment_declined', 'payment_timeout'], true);
  204. }
  205. protected function resolvePaymentUrl(array $result)
  206. {
  207. $data = $result['data'] ?? $result;
  208. foreach (['cashierUrl', 'cashier_url', 'payment_url', 'paymentUrl', 'redirect_url', 'url'] as $key) {
  209. if (!empty($data[$key])) {
  210. return $data[$key];
  211. }
  212. }
  213. return '';
  214. }
  215. protected function emailOrDefault($email, $userId)
  216. {
  217. return filter_var($email, FILTER_VALIDATE_EMAIL) ? $email : 'unknown' . $userId . '@example.com';
  218. }
  219. protected function stringOrDefault($value, $default)
  220. {
  221. $value = trim((string) $value);
  222. return $value === '' ? $default : $value;
  223. }
  224. }