LakalaAccountClass.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace bizHd\lakala\classes;
  3. use bizHd\base\classes\BaseClass;
  4. use common\components\AsyncConsole;
  5. use common\components\lakala\LakalaOnboardingClient;
  6. use Yii;
  7. /** 花掌柜拉卡拉收款账户数据访问及支付渠道授权状态刷新。 */
  8. class LakalaAccountClass extends BaseClass
  9. {
  10. public static $baseFile = '\bizHd\lakala\models\LakalaAccount';
  11. const AUTHORIZE_REFRESH_LOCK_PREFIX = 'lakala:authorize-refresh-';
  12. const AUTHORIZE_REFRESH_LOCK_SECONDS = 120;
  13. public static function dispatchAuthorizeStatesRefresh(array $accountIds)
  14. {
  15. $accountIds = array_values(array_unique(array_filter(array_map('intval', $accountIds), function ($id) {
  16. return $id > 0;
  17. })));
  18. if (empty($accountIds)) {
  19. return false;
  20. }
  21. $lockedIds = [];
  22. try {
  23. foreach ($accountIds as $accountId) {
  24. $key = self::AUTHORIZE_REFRESH_LOCK_PREFIX . $accountId;
  25. $locked = Yii::$app->redis->executeCommand('SET', [
  26. $key,
  27. (string)time(),
  28. 'EX',
  29. self::AUTHORIZE_REFRESH_LOCK_SECONDS,
  30. 'NX',
  31. ]);
  32. if ($locked === true || $locked === 'OK') {
  33. $lockedIds[] = $accountId;
  34. }
  35. }
  36. } catch (\Throwable $e) {
  37. Yii::warning('Unable to lock Lakala authorize refresh task: ' . $e->getMessage());
  38. self::releaseAuthorizeRefreshLocks($lockedIds);
  39. return false;
  40. }
  41. if (empty($lockedIds)) {
  42. return false;
  43. }
  44. $started = AsyncConsole::run([
  45. 'lakala-account/refresh-authorize-states',
  46. implode(',', $lockedIds),
  47. ], 'lakala-authorize-refresh.log');
  48. if (!$started) {
  49. self::releaseAuthorizeRefreshLocks($lockedIds);
  50. }
  51. return $started;
  52. }
  53. public static function refreshAuthorizeStates($accountId)
  54. {
  55. try {
  56. $account = self::getById((int)$accountId, true);
  57. if (empty($account)) {
  58. return true;
  59. }
  60. if ($account->wxAuthorizeState == 1 && $account->zfbAuthorizeState == 1) {
  61. return true;
  62. }
  63. $merchantNo = $account->merchantNo ?: '';
  64. $scanTermNo = $account->scanTermNo ?: '';
  65. $b2bTermNo = $account->b2bTermNo ?: '';
  66. if ($merchantNo === '' || $scanTermNo === '' || $b2bTermNo === '') {
  67. return true;
  68. }
  69. $client = new LakalaOnboardingClient();
  70. $account->wxAuthorizeState = self::authorizeState($client, $merchantNo, 'WXZF');
  71. $account->zfbAuthorizeState = self::authorizeState($client, $merchantNo, 'ZFBZF');
  72. $account->updateTime = date('Y-m-d H:i:s');
  73. if (!$account->save()) {
  74. throw new \RuntimeException(json_encode($account->getErrors(), JSON_UNESCAPED_UNICODE));
  75. }
  76. return true;
  77. } catch (\Throwable $e) {
  78. Yii::warning('Unable to refresh Lakala authorize state, accountId=' . (int)$accountId . ': ' . $e->getMessage());
  79. return false;
  80. }
  81. }
  82. private static function authorizeState($client, $merchantNo, $registerType)
  83. {
  84. $response = $client->query('/api/v3/tkbs/open_merchant_register_status_query', [
  85. 'merchant_no' => $merchantNo,
  86. 'register_type' => $registerType,
  87. ], 'both');
  88. Yii::info(json_encode($response));
  89. $data = $response['data'] ?? [];
  90. if (isset($data['authorize_state']) && ($data['authorize_state'] == 'AUTHORIZE_STATE_UNAUTHORIZED' || $data['authorize_state'] == 'UNAUTHORIZED')) {
  91. Yii::info('Lakala '.$merchantNo. ' '.$registerType. ' authorize state is UNAUTHORIZED');
  92. // 未认证
  93. return 0;
  94. }
  95. if (isset($data['authorize_state']) && ($data['authorize_state'] == 'AUTHORIZE_STATE_AUTHORIZED' || $data['authorize_state'] == 'AUTHORIZED')) {
  96. Yii::info('Lakala '.$merchantNo. ' '.$registerType. ' authorize state is AUTHORIZED');
  97. // 已认证
  98. return 1;
  99. }
  100. // 其他状态,默认未认证
  101. Yii::error('Lakala '.$merchantNo. ' '.$registerType. ' authorize state is UNKNOWN');
  102. return 0;
  103. }
  104. private static function releaseAuthorizeRefreshLocks(array $accountIds)
  105. {
  106. foreach ($accountIds as $accountId) {
  107. try {
  108. Yii::$app->redis->executeCommand('DEL', [self::AUTHORIZE_REFRESH_LOCK_PREFIX . $accountId]);
  109. } catch (\Throwable $e) {
  110. Yii::warning('Unable to release Lakala authorize refresh lock: ' . $e->getMessage());
  111. }
  112. }
  113. }
  114. }