| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- <?php
- namespace services\common;
- use common\enums\UserWalletEnum;
- use common\models\common\PaymentTransfer;
- use common\models\mall\MallAddons;
- use common\models\user\UserWallet;
- use common\models\user\UserWithdrawLog;
- use common\models\wechat\WechatTransferLog;
- /**
- * 提现转账服务
- */
- class WithdrawTransferService
- {
- const AUTH_TAG_LENGTH_BYTE = 16;
- const AUTH_NOTIFY_STATE = ['FAIL', 'CANCELLED']; // 只有转账失败或者订单已撤销时才需要回退金额
- /**
- * 微信转账回调
- */
- public function notify(array $data, string $appKey)
- {
- try {
- $resource = $data['resource'] ?? [];
- $resourceDecrypt = json_decode($this->transferDecrypt($resource, $appKey), true) ?? [];
- if (empty($resourceDecrypt)) {
- return json_encode(['code' => 'FAIL', 'message' => '操作失败']);
- }
- if (in_array($resourceDecrypt['state'], self::AUTH_NOTIFY_STATE)) {
- // 获取提现流水号
- $paymentTransfer = PaymentTransfer::find()->where(['order_no' => $resourceDecrypt['out_bill_no']])->asArray()->one();
- if (!$paymentTransfer) {
- return json_encode(['code' => 'FAIL', 'message' => '支付记录不存在']);
- }
- $withdrawal_source = $paymentTransfer['withdrawal_source'] ?? '';
- switch ($withdrawal_source) {
- case 'AiyunuoStoreWithdrawLog':
- if (MallAddons::isInstall($paymentTransfer->mall_id, 'Aiyunuo')) {
- $withdraw = new \addons\Aiyunuo\common\service\WithdrawTransferService();
- $res = $withdraw->refund($paymentTransfer);
- } else {
- $res = true;
- }
- break;
- case 'MchWithdrawLog':
- if (MallAddons::isInstall($paymentTransfer->mall_id, 'Mch')) {
- $withdraw = new \addons\Mch\common\services\WithdrawTransferService();
- $res = $withdraw->refund($paymentTransfer);
- } else {
- $res = true;
- }
- break;
- case 'LaoDaFu':
- if (MallAddons::isInstall($paymentTransfer->mall_id, 'LaoDaFu')) {
- $withdraw = new \addons\LaoDaFu\common\services\WithdrawTransferService();
- $res = $withdraw->refund($paymentTransfer);
- } else {
- $res = true;
- }
- break;
- case 'Store':
- if (MallAddons::isInstall($paymentTransfer->mall_id, 'Store')) {
- $withdraw = new \addons\Store\common\services\WithdrawTransferService();
- $res = $withdraw->refund($paymentTransfer);
- } else {
- $res = true;
- }
- break;
- case 'HigoWithdrawLog':
- $res = true;
- break;
- default:
- $res = $this->refund($paymentTransfer);
- break;
- }
- return $res;
- }
- $out_bill_no = $resourceDecrypt['out_bill_no'];
- $wechatTransferLog = \common\models\wechat\WechatTransferLog::find()->where(['out_trade_no' => $out_bill_no])->one();
- if(!empty($wechatTransferLog)){
- $transferResult = json_decode($wechatTransferLog->transfer_result,true);
- $transferResult['state'] = $resourceDecrypt['state'];
- $wechatTransferLog->transfer_result = json_encode($transferResult);
- $wechatTransferLog->save();
- }
- return true;
- } catch (\Exception $e) {
- \Yii::$app->custom->logs("提现转账回调失败", $e->getMessage());
- return false;
- }
- }
- /**
- * 微信转账数据解密
- * @param $resource
- * @param $appKey
- * @return false|string
- */
- protected function transferDecrypt($resource, $appKey)
- {
- $ciphertext = base64_decode($resource['ciphertext']);
- $nonce = $resource['nonce'];
- $text = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
- $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
- $associatedData = $resource['associated_data'];
- return openssl_decrypt($text, 'aes-256-gcm', $appKey, \OPENSSL_RAW_DATA, $nonce,
- $authTag, $associatedData);
- }
- /**
- * 回退提现
- */
- protected function refund(array $data): bool
- {
- $insertWallet = [];
- try {
- // 根据流水号获取提现记录
- $withdrawLog = UserWithdrawLog::find()->where(['id' => $data['withdrawal_source_id']])->one();
- if (!$withdrawLog) {
- throw new \Exception("提现记录不存在");
- }
- // 修改提现状态
- $withdrawLog->status = 4;
- if (!$withdrawLog->save()) {
- throw new \Exception("提现状态修改失败");
- }
- $insertWallet[] = [
- 'mall_id' => $withdrawLog->mall_id,
- 'user_id' => $withdrawLog->user_id,
- 'wallet_type' => $withdrawLog->from == 1 ? 'commission' : 'balance',
- 'is_frozen' => false,
- 'not_add_total' => 1,
- 'money' => $withdrawLog->num,
- 'desc' => '提现未领取回退',
- 'source_table' => 'user_wallet',
- 'from_type' => UserWalletEnum::WITHDRAWAL,
- 'capital_type' => UserWalletEnum::WITHDRAWAL_REFUND,
- 'source_table_id' => $withdrawLog->id,
- ];
- if (!empty($insertWallet)) {
- // 因为退款了并未扣减已提现金额。所以需要扣减已提现金额
- $user = UserWallet::findOne(['mall_id' => $withdrawLog->mall_id, 'user_id' => $withdrawLog->user_id]);
- if ($user) {
- if ($withdrawLog->from == 1) {
- $user->commission_withdrawal -= $withdrawLog->num;
- } else {
- $user->balance_withdrawal -= $withdrawLog->num;
- }
- $user->save();
- }
- $res = UserWalletService::batchHandleByQueue($insertWallet);
- if (empty($res)) throw new \Exception(UserWalletService::getStaticError());
- }
- return true;
- } catch (\Exception $e) {
- return false;
- }
- }
- }
|