| @@ -5,12 +5,14 @@ namespace App\Console\Commands\PoolTransfer; | |||
| use App\Console\Commands\BaseCommand; | |||
| use App\Exceptions\SkipException; | |||
| use App\Kintone\KintoneRecordQueryOperator; | |||
| use App\Kintone\Models\BankCheckResult; | |||
| use App\Kintone\Models\DropDown\SmbcPayment\SmbcPaymentStatus; | |||
| use App\Kintone\Models\SmbcAccountTransferResult; | |||
| use App\Kintone\Models\SmbcPayment; | |||
| use App\Kintone\Models\YuchoPaymentResult; | |||
| use App\Logic\PoolTransferManager; | |||
| use App\Util\CollectionUtil; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Support\Collection; | |||
| class MoveToPool extends BaseCommand | |||
| @@ -75,7 +77,7 @@ class MoveToPool extends BaseCommand | |||
| return self::RESULTCODE_SUCCESS; | |||
| } | |||
| public function handleData(YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult $payment) | |||
| public function handleData(YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult $payment) | |||
| { | |||
| $manager = new PoolTransferManager(); | |||
| @@ -83,12 +85,12 @@ class MoveToPool extends BaseCommand | |||
| } | |||
| /** | |||
| * @return Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult> | |||
| * @return Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult> | |||
| */ | |||
| public function getTargets() | |||
| { | |||
| /** | |||
| * @var Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult> | |||
| * @var Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult> | |||
| */ | |||
| $ret = collect(); | |||
| @@ -119,6 +121,22 @@ class MoveToPool extends BaseCommand | |||
| CollectionUtil::pushAll($ret, $targets); | |||
| $this->outputInfo(sprintf("口座振替:%d件", $targets->count())); | |||
| // バンクチェック | |||
| $query = BankCheckResult::getQuery()->whereNotIn(BankCheckResult::FIELD_POOL_DONE, ["済"]) | |||
| ->whereNotNull(BankCheckResult::FIELD_CUSTOMER_CODE) | |||
| ->where(BankCheckResult::FIELD_REMAINING_AMOUNT, 0, KintoneRecordQueryOperator::LE); | |||
| $targets = BankCheckResult::getAccess()->all($query); | |||
| CollectionUtil::pushAll($ret, $targets); | |||
| $this->outputInfo(sprintf("バンクチェック 支払完了:%d件", $targets->count())); | |||
| $query = BankCheckResult::getQuery()->whereNotIn(BankCheckResult::FIELD_POOL_DONE, ["済"]) | |||
| ->whereNotNull(BankCheckResult::FIELD_CUSTOMER_CODE) | |||
| ->where(BankCheckResult::FIELD_REMAINING_AMOUNT, 0, KintoneRecordQueryOperator::NEQ) | |||
| ->whereDate(BankCheckResult::FIELD_PAYMENT_EXPIRES_DATE, DateUtil::now(), KintoneRecordQueryOperator::LT); | |||
| $targets = BankCheckResult::getAccess()->all($query); | |||
| CollectionUtil::pushAll($ret, $targets); | |||
| $this->outputInfo(sprintf("バンクチェック 支払期限切れ:%d件", $targets->count())); | |||
| return $ret; | |||
| } | |||
| } | |||
| @@ -0,0 +1,60 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\BanckCheck; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Kintone\Models\BankCheckResult; | |||
| use App\Util\DateUtil; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Http\Response; | |||
| use Illuminate\Support\Carbon; | |||
| use Illuminate\Support\Str; | |||
| class EntryController extends WebController | |||
| { | |||
| public function name(): string | |||
| { | |||
| return "バンクチェック 受付"; | |||
| } | |||
| public function description(): string | |||
| { | |||
| return "バンクチェック 受付"; | |||
| } | |||
| public function __construct(protected EntryParam $param) | |||
| { | |||
| parent::__construct(); | |||
| } | |||
| protected function run(Request $request): Response | |||
| { | |||
| $param = $this->param; | |||
| if ($param->token !== config('custom.bank-check.token')) { | |||
| abort(403); | |||
| } | |||
| $model = new BankCheckResult(); | |||
| $model->customerCode = $param->customerCode; | |||
| $model->entryRecordNo = $param->entryRecordNo; | |||
| $model->shopOrderNo = $param->cod; | |||
| $model->paymentNo = $param->gid; | |||
| $model->orderCode = $param->god; | |||
| $model->entryResult = $param->rst; | |||
| $model->entryErrorCode = $param->ec; | |||
| $model->paymentPlanAmount = intval($param->am); | |||
| $model->paymentExpiresDate = Carbon::createFromFormat("Ymd", $param->exp); | |||
| $requestArr = $request->toArray(); | |||
| unset($requestArr["token"]); | |||
| $model->dataEntry = json_encode($requestArr); | |||
| $model->save(); | |||
| return response()->view('bank-check.ok'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\BanckCheck; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| /** | |||
| * @property string $gid 決済受付時に発行された決済番号 | |||
| * @property string $rst 決済結果(1:OK 2:NG) | |||
| * @property string $ap 入金:完了(BAN_SAL) | |||
| * @property string $ec エラーコード | |||
| * @property string $god オーダーコード | |||
| * @property string $cod 店舗側オーダー番号 | |||
| * @property string $am 決済金額 | |||
| * @property string $tx 税金額 | |||
| * @property string $sf 送料 | |||
| * @property string $ta 合計金額 | |||
| * @property string $bank 振込先口座情報(ドット「.」区切りの文字列)[銀行コード].[銀行名].[支店コード].[支店名].[口座種別].[口座番号].[口座名義] | |||
| * @property string $exp 支払期限(yyyymmdd形式) | |||
| * @property string $customerCode カスタム-顧客コード | |||
| * @property int $entryRecordNo カスタム-定期申込レコード番号 | |||
| * @property string $token カスタム-トークン | |||
| */ | |||
| class EntryParam extends BaseParam | |||
| { | |||
| public function rules(): array | |||
| { | |||
| return [ | |||
| 'gid' => $this->str(), | |||
| 'rst' => $this->str(), | |||
| 'ap' => $this->str(), | |||
| 'ec' => $this->str(), | |||
| 'god' => $this->str(), | |||
| 'cod' => $this->str(), | |||
| 'am' => $this->numeric(), | |||
| 'tx' => $this->numeric(), | |||
| 'sf' => $this->numeric(), | |||
| 'ta' => $this->numeric(), | |||
| 'bank' => $this->str(), | |||
| 'exp' => $this->str(), | |||
| 'customer_code' => $this->str(), | |||
| 'entry_record_no' => $this->numeric(), | |||
| 'token' => $this->str(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,100 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\BanckCheck; | |||
| use App\Exceptions\AppCommonException; | |||
| use App\Http\Controllers\Web\WebController; | |||
| use App\Kintone\Models\BankCheckResult; | |||
| use Illuminate\Http\Request; | |||
| use Illuminate\Http\Response; | |||
| use Illuminate\Support\Carbon; | |||
| class PaymentInfoController extends WebController | |||
| { | |||
| public function name(): string | |||
| { | |||
| return "バンクチェック 決済結果"; | |||
| } | |||
| public function description(): string | |||
| { | |||
| return "バンクチェック 決済結果"; | |||
| } | |||
| public function __construct(protected PaymentInfoParam $param) | |||
| { | |||
| parent::__construct(); | |||
| } | |||
| protected function run(Request $request): Response | |||
| { | |||
| $param = $this->param; | |||
| logger("リクエスト受信 bankcheck"); | |||
| if ($param->token !== config('custom.bank-check.token')) { | |||
| abort(403); | |||
| } | |||
| if ($param->ap === "BANK") { | |||
| $this->handleEntry(); | |||
| } else if ($param->ap === "BAN_SAL") { | |||
| $this->handlePayment(); | |||
| } | |||
| return response()->view('bank-check.ok'); | |||
| } | |||
| private function handleEntry() | |||
| { | |||
| $param = $this->param; | |||
| $model = new BankCheckResult(); | |||
| $model->customerCode = $param->customerCode; | |||
| $model->entryRecordNo = $param->entryRecordNo; | |||
| $model->shopOrderNo = $param->cod; | |||
| $model->paymentNo = $param->gid; | |||
| $model->orderCode = $param->god; | |||
| $model->entryResult = $param->rst; | |||
| $model->entryErrorCode = $param->ec; | |||
| $model->paymentPlanAmount = intval($param->am); | |||
| $model->paymentExpiresDate = Carbon::createFromFormat("Ymd", $param->exp); | |||
| $requestArr = request()->toArray(); | |||
| unset($requestArr["token"]); | |||
| $model->dataEntry = json_encode($requestArr); | |||
| $model->save(); | |||
| } | |||
| private function handlePayment() | |||
| { | |||
| $param = $this->param; | |||
| $model = BankCheckResult::getAccess() | |||
| ->first(BankCheckResult::getQuery()->where( | |||
| BankCheckResult::FIELD_SHOP_ORDER_NO, | |||
| $param->cod | |||
| )); | |||
| if ($model === null) { | |||
| throw new AppCommonException(sprintf( | |||
| "存在しない店舗側オーダー番号:[%s]", | |||
| $param->cod | |||
| )); | |||
| } | |||
| $model->paymentResult = $param->rst; | |||
| $model->paymentErrorCode = $param->ec; | |||
| $model->paymentAmount = intval($param->nk); | |||
| $model->paymentDate = Carbon::createFromFormat("Ymd", $param->nkd); | |||
| $requestArr = request()->toArray(); | |||
| unset($requestArr["token"]); | |||
| $model->dataResult = json_encode($requestArr); | |||
| $model->save(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,56 @@ | |||
| <?php | |||
| namespace App\Http\Controllers\Web\BanckCheck; | |||
| use App\Http\Controllers\Web\BaseParam; | |||
| /** | |||
| * @property string $gid 決済受付時に発行された決済番号 | |||
| * @property string $rst 決済結果(1:OK 2:NG) | |||
| * @property string $ap 入金:完了(BAN_SAL) | |||
| * @property string $ec エラーコード | |||
| * @property string $god オーダーコード | |||
| * @property string $cod 店舗側オーダー番号 | |||
| * @property string $am 決済金額 | |||
| * @property string $tx 税金額 | |||
| * @property string $sf 送料 | |||
| * @property string $ta 合計金額 | |||
| * @property string $id 発行ID | |||
| * @property string $ps 発行パスワード | |||
| * @property string $mf マッチングフラグ(1:マッチ2:過少3:過剰) | |||
| * @property string $nk 入金金額 | |||
| * @property string $nkd 入金日(yyyymmdd形式) | |||
| * @property string $bank 振込先口座情報(ドット「.」区切りの文字列)[銀行コード].[銀行名].[支店コード].[支店名].[口座種別].[口座番号].[口座名義] | |||
| * @property string $exp 支払期限(yyyymmdd形式) | |||
| * @property string $customerCode カスタム-顧客コード | |||
| * @property int $entryRecordNo カスタム-定期申込レコード番号 | |||
| * @property string $token カスタム-トークン | |||
| */ | |||
| class PaymentInfoParam extends BaseParam | |||
| { | |||
| public function rules(): array | |||
| { | |||
| return [ | |||
| 'gid' => $this->str(), | |||
| 'rst' => $this->str(), | |||
| 'ap' => $this->str(), | |||
| 'ec' => $this->str(true), | |||
| 'god' => $this->str(), | |||
| 'cod' => $this->str(), | |||
| 'am' => $this->numeric(), | |||
| 'tx' => $this->numeric(), | |||
| 'sf' => $this->numeric(), | |||
| 'ta' => $this->numeric(), | |||
| 'id' => $this->str(true), | |||
| 'ps' => $this->str(true), | |||
| 'mf' => $this->str(true), | |||
| 'nk' => $this->str(true), | |||
| 'nkd' => $this->str(true), | |||
| 'bank' => $this->str(true), | |||
| 'exp' => $this->str(), | |||
| 'customer_code' => $this->str(), | |||
| 'entry_record_no' => $this->numeric(), | |||
| 'token' => $this->str(), | |||
| ]; | |||
| } | |||
| } | |||
| @@ -0,0 +1,82 @@ | |||
| <?php | |||
| namespace App\Kintone\Models; | |||
| use Illuminate\Support\Carbon; | |||
| /** | |||
| * アプリ名 バンクチェック入金結果 | |||
| * | |||
| * @property string $customerCode 顧客コード | |||
| * @property string $customerName 顧客名 | |||
| * @property string $shopOrderNo 店舗側オーダー番号 | |||
| * @property int $entryRecordNo 定期申込レコード番号 | |||
| * @property ?string $paymentNo 決済番号 | |||
| * @property ?string $orderCode オーダーコード | |||
| * @property ?string $entryResult 受付結果 | |||
| * @property ?string $entryErrorCode 受付エラーコード | |||
| * @property ?int $paymentPlanAmount 予定金額 | |||
| * @property ?Carbon $paymentExpiresDate 支払期限 | |||
| * @property ?string $paymentResult 決済結果 | |||
| * @property ?string $paymentErrorCode 決済エラーコード | |||
| * @property ?Carbon $paymentDate 入金日 | |||
| * @property ?int $paymentAmount 入金金額 | |||
| * @property string[] $poolDone プール済み | |||
| * @property ?string $dataEntry 受信電文_受付 | |||
| * @property ?string $dataResult 受信電文_結果 | |||
| */ | |||
| class BankCheckResult extends KintoneModel | |||
| { | |||
| const CONFIG_KEY = "KINTONE_APP_BANK_CHECK_RESULT"; | |||
| const FIELD_CUSTOMER_CODE = "顧客コード"; | |||
| const FIELD_CUSTOMER_NAME = "顧客名"; | |||
| const FIELD_SHOP_ORDER_NO = "店舗側オーダー番号"; | |||
| const FIELD_ENTRY_RECORD_NO = "定期申込レコード番号"; | |||
| const FIELD_PAYMENT_NO = "決済番号"; | |||
| const FIELD_ORDER_CODE = "オーダーコード"; | |||
| const FIELD_ENTRY_RESULT = "受付結果"; | |||
| const FIELD_ENTRY_ERROR_CODE = "受付エラーコード"; | |||
| const FIELD_PAYMENT_PLAN_AMOUNT = "予定金額"; | |||
| const FIELD_PAYMENT_EXPIRES_DATE = "支払期限"; | |||
| const FIELD_PAYMENT_RESULT = "決済結果"; | |||
| const FIELD_PAYMENT_ERROR_CODE = "決済エラーコード"; | |||
| const FIELD_PAYMENT_DATE = "入金日"; | |||
| const FIELD_PAYMENT_AMOUNT = "入金金額"; | |||
| const FIELD_REMAINING_AMOUNT = "残金"; | |||
| const FIELD_POOL_DONE = "プール済み"; | |||
| const FIELD_DATA_ENTRY = "受信電文_受付"; | |||
| const FIELD_DATA_RESULT = "受信電文_結果"; | |||
| protected const FIELDS = [ | |||
| ...parent::FIELDS, | |||
| self::FIELD_CUSTOMER_CODE => FieldType::NUMBER, | |||
| self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_SHOP_ORDER_NO => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_ENTRY_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_PAYMENT_NO => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_ORDER_CODE => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_ENTRY_RESULT => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_ENTRY_ERROR_CODE => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_PAYMENT_PLAN_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_PAYMENT_EXPIRES_DATE => FieldType::DATE, | |||
| self::FIELD_PAYMENT_RESULT => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_PAYMENT_ERROR_CODE => FieldType::SINGLE_LINE_TEXT, | |||
| self::FIELD_PAYMENT_DATE => FieldType::DATE, | |||
| self::FIELD_PAYMENT_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_REMAINING_AMOUNT => FieldType::NUMBER, | |||
| self::FIELD_POOL_DONE => FieldType::CHECK_BOX, | |||
| self::FIELD_DATA_ENTRY => FieldType::MULTI_LINE_TEXT, | |||
| self::FIELD_DATA_RESULT => FieldType::MULTI_LINE_TEXT, | |||
| ]; | |||
| protected const FIELD_NAMES = [ | |||
| ...parent::FIELD_NAMES, | |||
| ]; | |||
| protected const RELATIONS = [ | |||
| Customer::class, | |||
| SeasonTicketContractEntry::class, | |||
| ]; | |||
| } | |||
| @@ -7,4 +7,5 @@ abstract class TransferMethod | |||
| const ACCOUNT_TRANSFER = "口座振替"; | |||
| const YUCHO = "ゆうちょ振込"; | |||
| const CVS = "コンビニ支払"; | |||
| const BANK_CHECK = "バンクチェック"; | |||
| } | |||
| @@ -19,6 +19,7 @@ use Illuminate\Support\Carbon; | |||
| * @property ?int incomeAccountTransferResultRecordNo | |||
| * @property ?int incomeYuchoTransferRecordNo | |||
| * @property ?int incomeCvsPaymentRecordNo | |||
| * @property ?int incomeBankCheckPaymentRecordNo | |||
| * @property ?int paymentPlanRecordNo | |||
| * @property ?int seasonContractRecordNo | |||
| */ | |||
| @@ -38,6 +39,7 @@ class PoolTransferHistory extends KintoneModel | |||
| const FIELD_INCOME_ACCOUNT_TRANSFER_RESULT_RECORD_NO = "口座振替結果レコード番号"; | |||
| const FIELD_INCOME_YUCHO_TRANSFER_RECORD_NO = "ゆうちょ振込レコード番号"; | |||
| const FIELD_INCOME_CVS_PAYMENT_RECORD_NO = "コンビニ支払レコード番号"; | |||
| const FIELD_INCOME_BANK_CHECK_PAYMENT_RECORD_NO = "バンクチェック支払レコード番号"; | |||
| const FIELD_PAYMENT_PLAN_RECORD_NO = "入金予定結果レコード番号"; | |||
| const FIELD_SEASON_CONTRACT_RECORD_NO = "車室情報管理レコード番号"; | |||
| @@ -56,6 +58,7 @@ class PoolTransferHistory extends KintoneModel | |||
| self::FIELD_INCOME_ACCOUNT_TRANSFER_RESULT_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_INCOME_YUCHO_TRANSFER_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_INCOME_CVS_PAYMENT_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_INCOME_BANK_CHECK_PAYMENT_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_PAYMENT_PLAN_RECORD_NO => FieldType::NUMBER, | |||
| self::FIELD_SEASON_CONTRACT_RECORD_NO => FieldType::NUMBER, | |||
| ]; | |||
| @@ -71,5 +74,6 @@ class PoolTransferHistory extends KintoneModel | |||
| SmbcAccountTransferResult::class, | |||
| Pool::class, | |||
| PaymentPlan::class, | |||
| BankCheckResult::class, | |||
| ]; | |||
| } | |||
| @@ -3,6 +3,7 @@ | |||
| namespace App\Logic; | |||
| use App\Exceptions\SkipException; | |||
| use App\Kintone\Models\BankCheckResult; | |||
| use App\Kintone\Models\DropDown\PoolTransferHistory\TransferMethod; | |||
| use App\Kintone\Models\DropDown\PoolTransferHistory\TransgerType; | |||
| use App\Kintone\Models\Pool; | |||
| @@ -18,12 +19,12 @@ use App\Util\DateUtil; | |||
| class PoolTransferManager | |||
| { | |||
| private SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|null $payment = null; | |||
| private SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult|null $payment = null; | |||
| private Pool|null $pool = null; | |||
| private PoolTransferHistory|null $history = null; | |||
| public function moveToPool(SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult $payment): Pool | |||
| public function moveToPool(SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult $payment): Pool | |||
| { | |||
| $this->clear(); | |||
| @@ -89,6 +90,10 @@ class PoolTransferManager | |||
| $history->incomeMethod = TransferMethod::YUCHO; | |||
| $history->incomeYuchoTransferRecordNo = $this->payment->getRecordId(); | |||
| } | |||
| if ($this->payment instanceof BankCheckResult) { | |||
| $history->incomeMethod = TransferMethod::BANK_CHECK; | |||
| $history->incomeBankCheckPaymentRecordNo = $this->payment->getRecordId(); | |||
| } | |||
| $this->history = $history; | |||
| } | |||
| @@ -4,5 +4,8 @@ return [ | |||
| "ht-ic-web" => [ | |||
| 'apiKey' => env("HT_IC_WEB_API_KEY", ""), | |||
| 'url' => env("HT_IC_WEB_URL", ""), | |||
| ], | |||
| "bank-check" => [ | |||
| 'token' => env("BANK_CHECK_TOKEN", ""), | |||
| ] | |||
| ]; | |||
| @@ -54,6 +54,7 @@ return [ | |||
| ...App\Kintone\Models\YuchoPaymentResult::setConfig(), | |||
| ...App\Kintone\Models\Pool::setConfig(), | |||
| ...App\Kintone\Models\PoolTransferHistory::setConfig(), | |||
| ...App\Kintone\Models\BankCheckResult::setConfig(), | |||
| ], | |||
| ]; | |||
| @@ -0,0 +1,5 @@ | |||
| <html> | |||
| <body>ok</body> | |||
| </html> | |||
| @@ -25,5 +25,9 @@ Route::get("/test/bank", function () { | |||
| return view('bank-test'); | |||
| }); | |||
| // BANK CHECK WEBHOOK | |||
| RouteHelper::get('/bank-check/info', App\Http\Controllers\Web\BanckCheck\PaymentInfoController::class); | |||
| // ルーティングで適合しない場合はフロント側のRoutingにゆだねる | |||
| RouteHelper::get('/{any?}', App\Http\Controllers\Web\IndexController::class)->where('any', '.*'); | |||