UrsDepositWebhook.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace ThirdParty\Urs\Webhook;
  3. use App\Module\ThirdParty\Models\ThirdPartyService as ServiceModel;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Facades\Log;
  6. use Illuminate\Support\Facades\DB;
  7. /**
  8. * URS充值通知Webhook处理器
  9. *
  10. * 专门处理充值相关的Webhook通知
  11. */
  12. class UrsDepositWebhook extends \ThirdParty\Urs\Webhook\WebhookReceiver
  13. {
  14. /**
  15. * 构造函数
  16. *
  17. * @param string $serviceCode 服务代码
  18. * @param Request $request 请求对象
  19. * @param ServiceModel $service 服务配置对象
  20. */
  21. public function __construct(string $serviceCode, Request $request, ServiceModel $service)
  22. {
  23. parent::__construct($serviceCode, $request, $service);
  24. }
  25. /**
  26. * 处理充值通知
  27. *
  28. * @param string $action 操作类型(固定为deposit)
  29. * @param Request $request 请求对象
  30. * @return array
  31. * @throws \Exception
  32. */
  33. protected function handler(string $action, Request $request): array
  34. {
  35. // 验证操作类型
  36. if ($action !== 'deposit') {
  37. throw new \Exception("此处理器只能处理deposit操作,当前操作: {$action}");
  38. }
  39. // 验证必需字段
  40. $this->validateDepositRequest($request);
  41. // 处理充值通知
  42. return $this->processDepositNotification($request->get('user_id'), $request->get('amount'), $request->get('order_id'));
  43. }
  44. /**
  45. * 验证充值请求
  46. *
  47. * @param Request $request 请求对象
  48. * @throws \Exception
  49. */
  50. protected function validateDepositRequest(Request $request): void
  51. {
  52. $requiredFields = [ 'user_id', 'amount', 'order_id' ];
  53. foreach ($requiredFields as $field) {
  54. if (!$request->has($field)) {
  55. throw new \Exception("缺少必需字段: {$field}");
  56. }
  57. }
  58. // 验证用户ID
  59. $userId = $request->input('user_id');
  60. if (!is_numeric($userId) || $userId <= 0) {
  61. throw new \Exception('用户ID格式无效');
  62. }
  63. // 验证金额
  64. $amount = $request->input('amount');
  65. if (!is_numeric($amount) || $amount <= 0) {
  66. throw new \Exception('充值金额必须大于0');
  67. }
  68. // 验证订单ID
  69. $orderId = $request->input('order_id');
  70. if (empty($orderId)) {
  71. throw new \Exception('订单ID不能为空');
  72. }
  73. }
  74. /**
  75. * 处理充值通知
  76. *
  77. * @param int $user_id URS用户ID
  78. * @param string $amount 充值金额
  79. * @param string $order_id URS订单ID
  80. * @return array
  81. */
  82. protected function processDepositNotification($user_id, $amount, $order_id): array
  83. {
  84. // 记录处理日志
  85. Log::info("URS充值通知处理开始", [
  86. 'urs_user_id' => $user_id,
  87. 'amount' => $amount,
  88. 'order_id' => $order_id,
  89. 'request_id' => $this->getRequestId(),
  90. ]);
  91. try {
  92. /**
  93. * 三方应用ID
  94. * @var int $thirdPartyAppId
  95. */
  96. $thirdPartyAppId = $this->service->id;
  97. // 1. 根据URS用户ID获取农场用户ID
  98. $farmUserId = \App\Module\UrsPromotion\Services\UrsUserMappingService::getFarmUserId($user_id);
  99. if (!$farmUserId) {
  100. Log::error("URS充值失败:未找到用户映射关系", [
  101. 'urs_user_id' => $user_id,
  102. 'order_id' => $order_id,
  103. ]);
  104. throw new \Exception("用户未进入农场系统,无法完成充值");
  105. }
  106. // 2. 开启数据库事务并使用Transfer模块完成充值钻石操作
  107. $result = DB::transaction(function () use ($thirdPartyAppId, $farmUserId, $user_id, $amount, $order_id) {
  108. return \App\Module\Transfer\Services\TransferThirdPartyService::createRechargeOrder(
  109. thirdPartyAppId: $thirdPartyAppId,
  110. farmUserId: $farmUserId,
  111. thirdPartyUserId: (string)$user_id,
  112. thirdPartyAmount: $amount,
  113. order_id: $order_id,
  114. remark: "URS充值 - 订单号: {$order_id}",
  115. callbackData: [
  116. 'urs_order_id' => $order_id,
  117. 'urs_user_id' => $user_id,
  118. 'source' => 'urs_deposit_webhook'
  119. ]
  120. );
  121. });
  122. // 3. 检查充值结果
  123. if (is_string($result)) {
  124. // 充值失败
  125. Log::error("URS充值失败", [
  126. 'urs_user_id' => $user_id,
  127. 'farm_user_id' => $farmUserId,
  128. 'third_party_app_id' => $thirdPartyAppId,
  129. 'amount' => $amount,
  130. 'order_id' => $order_id,
  131. 'error' => $result,
  132. ]);
  133. throw new \Exception("充值失败: {$result}");
  134. }
  135. // 4. 充值成功,记录成功日志
  136. Log::info("URS充值成功", [
  137. 'urs_user_id' => $user_id,
  138. 'farm_user_id' => $farmUserId,
  139. 'third_party_app_id' => $thirdPartyAppId,
  140. 'amount' => $amount,
  141. 'order_id' => $order_id,
  142. 'transfer_order_id' => $result->id,
  143. 'business_id' => $result->out_order_id,
  144. 'actual_amount' => $result->out_amount,
  145. ]);
  146. // 5. 返回成功响应
  147. return [
  148. 'rorder_id' => $result->out_order_id, // 返回Transfer模块生成的业务订单ID
  149. 'transfer_order_id' => $result->id, // Transfer模块的内部订单ID
  150. 'actual_amount' => $result->out_amount, // 实际到账金额
  151. 'status' => 'success'
  152. ];
  153. } catch (\Exception $e) {
  154. // 记录异常日志
  155. Log::error("URS充值处理异常", [
  156. 'urs_user_id' => $user_id,
  157. 'amount' => $amount,
  158. 'order_id' => $order_id,
  159. 'error' => $e->getMessage(),
  160. 'trace' => $e->getTraceAsString(),
  161. ]);
  162. // 重新抛出异常,让上层处理
  163. throw $e;
  164. }
  165. }
  166. }