Bladeren bron

クレジットカード対応

master
sosuke.iwabuchi 1 jaar geleden
bovenliggende
commit
a1df1aec04
30 gewijzigde bestanden met toevoegingen van 869 en 11 verwijderingen
  1. +1
    -0
      app/Codes/Email.php
  2. +14
    -3
      app/Console/Commands/PoolTransfer/MoveToPool.php
  3. +46
    -0
      app/Email/Members/RegisterCreditcard.php
  4. +0
    -1
      app/Http/Controllers/Web/Auth/LoginCheckController.php
  5. +2
    -0
      app/Http/Controllers/Web/Auth/LoginController.php
  6. +51
    -0
      app/Http/Controllers/Web/Customer/ChangePaymentMethodCreditcardOrderController.php
  7. +9
    -0
      app/Http/Controllers/Web/Customer/ChangePaymentMethodCreditcardOrderParam.php
  8. +7
    -0
      app/Http/Controllers/Web/Email/EmailSendController.php
  9. +8
    -2
      app/Http/Controllers/Web/RobotPayment/BanckCheck/PaymentInfoController.php
  10. +107
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentInfoController.php
  11. +50
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentInfoParam.php
  12. +107
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentResultController.php
  13. +42
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentResultParam.php
  14. +34
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTestController.php
  15. +13
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTestParam.php
  16. +121
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTokenCheckController.php
  17. +18
    -0
      app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTokenCheckParam.php
  18. +34
    -0
      app/Http/Controllers/Web/RobotPayment/PaymentInfoIndexController.php
  19. +1
    -1
      app/Kintone/KintoneAccess.php
  20. +27
    -0
      app/Kintone/Models/ChangePaymentMethodCreditcardOrderApplication.php
  21. +48
    -0
      app/Kintone/Models/CreditcardAutoPaymentInfo.php
  22. +57
    -0
      app/Kintone/Models/CreditcardAutoPaymentResult.php
  23. +33
    -0
      app/Kintone/Models/Customer.php
  24. +1
    -0
      app/Kintone/Models/DropDown/PoolTransferHistory/TransferMethod.php
  25. +4
    -0
      app/Kintone/Models/PoolTransferHistory.php
  26. +10
    -0
      app/Kintone/Models/SeasonTicketContractPlan.php
  27. +9
    -0
      app/Logic/GeneralApplicationManager.php
  28. +7
    -2
      app/Logic/PoolTransferManager.php
  29. +3
    -0
      routes/api.php
  30. +5
    -2
      routes/web.php

+ 1
- 0
app/Codes/Email.php Bestand weergeven

@@ -11,4 +11,5 @@ enum Email: string
case ENTRY_PAYMENT_COMPLETE = '申込承認';
case CHANGE_PLAN_ORDER_APPROVE = 'プラン変更完了';
case COULD_NOT_PEY_NOTICE = '口座振替・未納者通知';
case REGISTER_CREDITCARD = 'クレジットカード登録';
}

+ 14
- 3
app/Console/Commands/PoolTransfer/MoveToPool.php Bestand weergeven

@@ -6,6 +6,7 @@ use App\Console\Commands\BaseCommand;
use App\Exceptions\SkipException;
use App\Kintone\KintoneRecordQueryOperator;
use App\Kintone\Models\BankCheckResult;
use App\Kintone\Models\CreditcardAutoPaymentResult;
use App\Kintone\Models\DropDown\SmbcPayment\SmbcPaymentStatus;
use App\Kintone\Models\SmbcAccountTransferResult;
use App\Kintone\Models\SmbcPayment;
@@ -77,7 +78,7 @@ class MoveToPool extends BaseCommand
return self::RESULTCODE_SUCCESS;
}

public function handleData(YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult $payment)
public function handleData(YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult|CreditcardAutoPaymentResult $payment)
{

$manager = new PoolTransferManager();
@@ -85,12 +86,12 @@ class MoveToPool extends BaseCommand
}

/**
* @return Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult>
* @return Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult|CreditcardAutoPaymentResult>
*/
public function getTargets()
{
/**
* @var Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult>
* @var Collection<int ,YuchoPaymentResult|SmbcPayment|SmbcAccountTransferResult|BankCheckResult|CreditcardAutoPaymentResult>
*/
$ret = collect();

@@ -129,6 +130,7 @@ 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::NEQ)
@@ -137,6 +139,15 @@ class MoveToPool extends BaseCommand
CollectionUtil::pushAll($ret, $targets);
$this->outputInfo(sprintf("バンクチェック 支払期限切れ:%d件", $targets->count()));

// クレジットカード
$query = CreditcardAutoPaymentResult::getQuery()->whereNotIn(CreditcardAutoPaymentResult::FIELD_POOL_DONE, ["済"])
->whereNotNull(CreditcardAutoPaymentResult::FIELD_CUSTOMER_CODE)
->where(CreditcardAutoPaymentResult::FIELD_PAYMENT_AMOUNT, 0, KintoneRecordQueryOperator::GT);
$targets = CreditcardAutoPaymentResult::getAccess()->all($query);
CollectionUtil::pushAll($ret, $targets);
$this->outputInfo(sprintf("クレジットカード支払 :%d件", $targets->count()));


return $ret;
}
}

+ 46
- 0
app/Email/Members/RegisterCreditcard.php Bestand weergeven

@@ -0,0 +1,46 @@
<?php

namespace App\Email\Members;

use App\Kintone\Models\ChangePaymentMethodCreditcardOrderApplication;
use App\Kintone\Models\Customer;

/**
* クレジットカード登録案内
*/
class RegisterCreditcard extends Members
{
public function __construct(
private ChangePaymentMethodCreditcardOrderApplication $application,
protected ?Customer $customer = null,
) {
if ($customer === null) {
$customer = $application->getCustomer();
}
parent::__construct($customer);
}

public function getTemplateName(): string
{
return 'emails.members.register_creditcard';
}

public function getSubject(): string
{
return "クレジットカード登録のご案内";
}

public function getMemberParams(): array
{
return [
'url' => $this->getAppUrl([
'dashboard',
'robot-payment',
'creditcard',
'register',
$this->application->token
]),
'expires_at' => $this->application->tokenExpiresAt->format('Y/m/d H:i')
];
}
}

+ 0
- 1
app/Http/Controllers/Web/Auth/LoginCheckController.php Bestand weergeven

@@ -38,7 +38,6 @@ class LoginCheckController extends WebController
$users = User::whereEmail($param->email)
->get();
foreach ($users as $user) {
info($user->toArray());
if (!Hash::check($param->password, $user->password)) {
return $this->failedResponse();
}


+ 2
- 0
app/Http/Controllers/Web/Auth/LoginController.php Bestand weergeven

@@ -65,5 +65,7 @@ class LoginController extends WebController
Auth::login($user);
return $this->successResponse($customer->toArray());
}

return $this->failedResponse();
}
}

+ 51
- 0
app/Http/Controllers/Web/Customer/ChangePaymentMethodCreditcardOrderController.php Bestand weergeven

@@ -0,0 +1,51 @@
<?php

namespace App\Http\Controllers\Web\Customer;

use App\Http\Controllers\Web\WebController;
use App\Kintone\Models\ChangePaymentMethodCreditcardOrderApplication;
use App\Kintone\Models\Customer;
use App\Logic\GeneralApplicationManager;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ChangePaymentMethodCreditcardOrderController extends WebController
{

public function name(): string
{
return "支払方法クレジット変更申請";
}

public function description(): string
{
return "支払方法クレジット変更申請";
}


public function __construct(protected ChangePaymentMethodCreditcardOrderParam $param)
{
parent::__construct();
$this->middleware('auth:sanctum');
}

protected function run(Request $request): JsonResponse
{

$customer = Customer::getSelf();

if (!$customer->canPayByCreditcard()) {
return $this->failedResponse();
}

$application = new ChangePaymentMethodCreditcardOrderApplication();
$manager = new GeneralApplicationManager($application);
$manager
->setCustomer($customer)
->makeApplication();

$application->save();

return $this->successResponse();
}
}

+ 9
- 0
app/Http/Controllers/Web/Customer/ChangePaymentMethodCreditcardOrderParam.php Bestand weergeven

@@ -0,0 +1,9 @@
<?php

namespace App\Http\Controllers\Web\Customer;

use App\Http\Controllers\Web\NoneParams;

class ChangePaymentMethodCreditcardOrderParam extends NoneParams
{
}

+ 7
- 0
app/Http/Controllers/Web/Email/EmailSendController.php Bestand weergeven

@@ -8,10 +8,12 @@ use App\Email\Members\ChangePlanOrderApprove;
use App\Email\Members\CouldNotPayNotice;
use App\Email\Members\EntryApprove;
use App\Email\Members\EntryPaymentComplete;
use App\Email\Members\RegisterCreditcard;
use App\Email\Members\TerminateOrderApprove;
use App\Email\Members\UserInfoUpdateOrderApprove;
use App\Email\Members\VehicleInfoUpdateOrderApprove;
use App\Http\Controllers\Web\FromKintoneController;
use App\Kintone\Models\ChangePaymentMethodCreditcardOrderApplication;
use App\Kintone\Models\ChangePlanApplication;
use App\Kintone\Models\PaymentPlan;
use App\Kintone\Models\SeasonTicketContract;
@@ -128,6 +130,11 @@ class EmailSendController extends FromKintoneController
$this->setEmail(new CouldNotPayNotice($seasonTicketContract, $paymentPlan));
return;
}
if ($emailId === Email::REGISTER_CREDITCARD) {
$application = ChangePaymentMethodCreditcardOrderApplication::findByApplicationNo($this->param->applicationNo);
$this->setEmail(new RegisterCreditcard($application));
return;
}


if ($this->email === null || $this->emailManager === null) {


+ 8
- 2
app/Http/Controllers/Web/RobotPayment/BanckCheck/PaymentInfoController.php Bestand weergeven

@@ -64,7 +64,10 @@ class PaymentInfoController extends WebController

$requestArr = request()->toArray();
unset($requestArr["token"]);
$model->dataEntry = json_encode($requestArr);
$model->dataEntry = json_encode(
$requestArr,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
);

$model->save();
}
@@ -93,7 +96,10 @@ class PaymentInfoController extends WebController

$requestArr = request()->toArray();
unset($requestArr["token"]);
$model->dataResult = json_encode($requestArr);
$model->dataResult = json_encode(
$requestArr,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
);

$model->save();
}


+ 107
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentInfoController.php Bestand weergeven

@@ -0,0 +1,107 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\WebController;
use App\Kintone\Models\CreditcardAutoPaymentInfo;
use App\Kintone\Models\CreditcardAutoPaymentResult;
use App\Kintone\Models\Customer;
use App\Util\DateUtil;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use LogicException;

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("リクエスト受信 creditcard", ["param" => $request->all()]);

// 認証チェック
// 初回の決済結果はトークン付で送信されるのでチェックする
if ($param->token !== config('custom.creditcard.token')) {
abort(403);
}

$customer = Customer::findByCustomerCode($param->customerCode);

$customer->paymentMethod = "クレジットカード";

$model = new CreditcardAutoPaymentInfo();

$model->customerCode = $param->customerCode;
$model->autoPaymentNo = $param->acid;
$model->shopOrderNo = $param->cod;
$model->paymentInterval = $this->getPaymentInterval();
$model->paymentAmount = $this->getPaymentAmount();

// 機密な情報をリクエストデータから除外して登録する
$requestArr = request()->toArray();
unset($requestArr["token"]);
unset($requestArr["id"]);
unset($requestArr["pa"]);
$model->dataResult = json_encode(
$requestArr,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
);

$model->save();
$customer->save();

return response()->view('robot-payment.creditcard.ok');
}

private function getPaymentAmount(): int
{
$param = $this->param;
return intval($param->acam) + intval($param->actx) + intval($param->acsf);
}

private function getPaymentInterval(): string
{
$code = $this->param->actp;
if ($code === "2") {
return "毎週課金";
}
if ($code === "3") {
return "隔週課金";
}
if ($code === "4") {
return "毎月課金";
}
if ($code === "5") {
return "隔月課金";
}
if ($code === "6") {
return "3ヶ月課金";
}
if ($code === "7") {
return "6ヶ月課金";
}
if ($code === "8") {
return "1年課金";
}

return "";
}
}

+ 50
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentInfoParam.php Bestand weergeven

@@ -0,0 +1,50 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\BaseParam;

/**
* @property string $gid 決済番号 決済毎に発行されるユニークID
* @property string $rst 決済結果(1:決済成功 2:決済失敗)
* @property string $ap カード会社承認番号 決済毎に発行されるユニークID
* @property ?string $ec エラーコード
* @property string $god オーダーコード 決済毎に発行されるユニークID
* @property string $cod 店舗オーダー番号 決済データ送信時に送信された店舗オーダー番号
* @property ?int $am 決済金額
* @property ?int $tx 税金額
* @property ?int $sf 送料
* @property ?int $ta 合計金額
* @property ?int $acam 自動課金決済金額
* @property ?int $actx 自動課金税金額
* @property ?int $acsf 自動課金送料
* @property ?string $actp 自動課金周期
* @property string $acid 自動課金番号 対象の自動課金番号
* @property ?string $customerCode カスタム-顧客コード
* @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(true),
'sf' => $this->numeric(true),
'ta' => $this->numeric(true),
'acam' => $this->numeric(true),
'actx' => $this->numeric(true),
'acsf' => $this->numeric(true),
'actp' => $this->str(true),
'acid' => $this->str(),
'customer_code' => $this->str(true),
'token' => $this->str(true),
];
}
}

+ 107
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentResultController.php Bestand weergeven

@@ -0,0 +1,107 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\WebController;
use App\Kintone\Models\CreditcardAutoPaymentInfo;
use App\Kintone\Models\CreditcardAutoPaymentResult;
use App\Util\DateUtil;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use LogicException;

class PaymentResultController extends WebController
{

public function name(): string
{
return "クレジットカード 決済結果";
}

public function description(): string
{
return "クレジットカード 決済結果";
}


public function __construct(protected PaymentResultParam $param)
{
parent::__construct();
}

protected function run(Request $request): Response
{
$param = $this->param;
logger("リクエスト受信 creditcard result", ["param" => $request->all()]);

try {

$info = CreditcardAutoPaymentInfo::getAccess()->first(
CreditcardAutoPaymentInfo::getQuery()
->where(CreditcardAutoPaymentInfo::FIELD_AUTO_PAYMENT_NO, $param->acid)
->where(CreditcardAutoPaymentInfo::FIELD_SHOP_ORDER_NO, $param->cod)
);
} catch (ModelNotFoundException $e) {
Log::error(sprintf(
"自動課金情報が存在しないため、クレジットカードの決済結果保存不可 自動課金番号<%s> 店舗側オーダー番号<%s>",
$param->acid,
$param->cod
));
throw $e;
}

$this->クレジット支払結果登録($info);

return response()->view('robot-payment.creditcard.ok');
}


private function クレジット支払結果登録(CreditcardAutoPaymentInfo $info)
{
$param = $this->param;

$result = new CreditcardAutoPaymentResult();
$result->creditcardAutoPaymentNo = $info->autoPaymentNo;
$result->paymentNo = $param->gid;
$result->paymentDate = DateUtil::now();
$result->paymentResult = $this->get決済結果($param->rst);
$result->errorCode = $param->ec;
$result->paymentAmount = $info->paymentAmount;

// 機密な情報をリクエストデータから除外して登録する
$requestArr = request()->toArray();
unset($requestArr["token"]);
unset($requestArr["id"]);
unset($requestArr["pa"]);
$result->dataResult = json_encode(
$requestArr,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
);

$result->save();
}

private function get決済結果(string $paymentResultCode): string
{
if ($paymentResultCode === "1") {
return "決済成功";
}
if ($paymentResultCode === "2") {
return "決済失敗";
}
if ($paymentResultCode === "3") {
return "リトライ課金失敗";
}
if ($paymentResultCode === "4") {
return "ユーザー様による課金停止";
}
if ($paymentResultCode === "5") {
return "お試し期間中にリトライ課金課金2回失敗";
}

throw new Exception("不正な決済結果コード " . $paymentResultCode);
}
}

+ 42
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/PaymentResultParam.php Bestand weergeven

@@ -0,0 +1,42 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\BaseParam;

/**
* @property string $gid 決済番号 決済毎に発行されるユニークID
* @property string $rst 決済結果(1:決済成功 2:決済失敗)
* @property string $ap カード会社承認番号 決済毎に発行されるユニークID
* @property ?string $ec エラーコード
* @property string $god オーダーコード 決済毎に発行されるユニークID
* @property string $cod 店舗オーダー番号 決済データ送信時に送信された店舗オーダー番号
* @property ?int $am 決済金額
* @property ?int $tx 税金額
* @property ?int $sf 送料
* @property ?int $ta 合計金額
* @property string $acid 自動課金番号 対象の自動課金番号
* @property ?string $customerCode カスタム-顧客コード
* @property ?string $token カスタム-トークン
*/
class PaymentResultParam 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(true),
'sf' => $this->numeric(true),
'ta' => $this->numeric(true),
'acid' => $this->str(),
'customer_code' => $this->str(true),
'token' => $this->str(true),
];
}
}

+ 34
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTestController.php Bestand weergeven

@@ -0,0 +1,34 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\WebController;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class RegisterTestController extends WebController
{

public function name(): string
{
return "クレジットカード 登録画面表示(テスト用)";
}

public function description(): string
{
return "クレジットカード 登録画面表示(テスト用)";
}



public function __construct(protected RegisterTestParam $param)
{
parent::__construct();
}

protected function run(Request $request): Response
{

return response()->view('robot-payment.creditcard.register');
}
}

+ 13
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTestParam.php Bestand weergeven

@@ -0,0 +1,13 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\BaseParam;

class RegisterTestParam extends BaseParam
{
public function rules(): array
{
return [];
}
}

+ 121
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTokenCheckController.php Bestand weergeven

@@ -0,0 +1,121 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Exceptions\AppCommonException;
use App\Http\Controllers\Web\WebController;
use App\Kintone\Models\ChangePaymentMethodCreditcardOrderApplication;
use App\Kintone\Models\Customer;
use App\Kintone\Models\SeasonTicketContract;
use App\Models\User;
use App\Util\DateUtil;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

class RegisterTokenCheckController extends WebController
{

public function name(): string
{
return "クレジットカード 新規登録用トークンチェック";
}

public function description(): string
{
return "クレジットカード 新規登録用トークンチェック";
}

private User $user;
private Customer $customer;

public function __construct(protected RegisterTokenCheckParam $param)
{
parent::__construct();
$this->middleware('auth:sanctum');
}

protected function run(Request $request): JsonResponse
{
$param = $this->param;

$application = ChangePaymentMethodCreditcardOrderApplication::getAccess()->first(
ChangePaymentMethodCreditcardOrderApplication::getQuery()
->where(ChangePaymentMethodCreditcardOrderApplication::FIELD_TOKEN, $param->token)
);

// トークン有効期限チェック
$now = DateUtil::now();
if ($application->tokenExpiresAt !== null && $application->tokenExpiresAt->lt($now)) {
return $this->failedResponse();
}

$this->user = Auth::user();
$this->customer = Customer::findByCustomerCode($this->user->kintone_customer_code);

// 申請可能チェック
if ($this->customer->canApplyToChangePaymentMethodCreditcard() === false) {
return $this->failedResponse();
}

// 申請パラメーターの返却
$ret = [
"url" => "https://credit.j-payment.co.jp/link/creditcard",
"shop_code" => "128522",
'customer_code' => $this->user->kintone_customer_code,
'token' => config('custom.creditcard.token'),
'payment_type' => "CREDITCARD",
'job_type' => "CAPTURE",
'tax' => "0",
'send_fee' => "0",
'amount' => "0",
"interval" => "4", // 毎月
"payment_day" => "27",
"auto_amount" => $this->getAmount(),
"target_date" => $this->getTargetDate(),
"email" => $this->customer->email,
'phone_number' => $this->customer->phoneNumber,
"order_no" => Str::uuid()->toString(),
];

return $this->successResponse($ret);
}

private function getAmount(): string
{
// 全契約を集計する
$targets = SeasonTicketContract::getAccess()->all(
SeasonTicketContract::getQuery()
->where(SeasonTicketContract::FIELD_CUSTOMER_CODE, $this->user->kintone_customer_code)
);

$amount = 0;
foreach ($targets as $target) {
if ($target->isTerminated()) {
continue;
}
$plan = $target->getPlan();
if (!$plan->canPayByCreditcard()) {
throw new AppCommonException("クレジット支払できない契約が存在");
}

$amount += intval($plan->amount ?? 0);
}

return strval($amount);
}


private function getTargetDate(): string
{
/**
* 翌月の27日を指定する
*/
$target = DateUtil::now()
->addMonth()
->setDay(27);

return $target->format("Y/m/d");
}
}

+ 18
- 0
app/Http/Controllers/Web/RobotPayment/CreditCard/RegisterTokenCheckParam.php Bestand weergeven

@@ -0,0 +1,18 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment\CreditCard;

use App\Http\Controllers\Web\BaseParam;

/**
* @property string $token
*/
class RegisterTokenCheckParam extends BaseParam
{
public function rules(): array
{
return [
"token" => $this->str(),
];
}
}

+ 34
- 0
app/Http/Controllers/Web/RobotPayment/PaymentInfoIndexController.php Bestand weergeven

@@ -0,0 +1,34 @@
<?php

namespace App\Http\Controllers\Web\RobotPayment;

use App\Http\Controllers\Web\WebController;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;

class PaymentInfoIndexController extends BaseController
{

public function description(): string
{
return "決済結果の受信";
}

public function entry(Request $request)
{
return $this->getController($request)->entry($request);
}

private function getController(Request $request): WebController
{
if ($request->get("payment_type") === "CREDITCARD") {
return app()
->make(\App\Http\Controllers\Web\RobotPayment\CreditCard\PaymentInfoController::class);
}
if ($request->get('payment_type') === "BANK_CHECK") {
return app()
->make(\App\Http\Controllers\Web\RobotPayment\BanckCheck\PaymentInfoController::class);
}
abort(403);
}
}

+ 1
- 1
app/Kintone/KintoneAccess.php Bestand weergeven

@@ -177,7 +177,7 @@ class KintoneAccess
{
$list = $this->some($query);
if ($list->count() !== 1) {
throw new ModelNotFoundException(sprintf("モデル取得数エラー %s count:%d", $this->appName, $list->count()));
throw new ModelNotFoundException(sprintf("モデル取得数エラー %s count:%d queey:<%s>", $this->appName, $list->count(), $query->toQuery()));
}
return $list->first();
}


+ 27
- 0
app/Kintone/Models/ChangePaymentMethodCreditcardOrderApplication.php Bestand weergeven

@@ -0,0 +1,27 @@
<?php

namespace App\Kintone\Models;

use Illuminate\Support\Carbon;

/**
* アプリ名 各種申請 [クレジット支払方法変更申請]
*
* @property string $token トークン
* @property ?Carbon $tokenExpiresAt トークン有効期限
*/
class ChangePaymentMethodCreditcardOrderApplication extends GeneralApplication
{
const FIELD_TOKEN = "クレジット支払変更申請_トークン";
const FIELD_TOKEN_EXPIRES_AT = "クレジット支払変更申請_有効期限";

protected const FIELDS = [
...parent::FIELDS,
self::FIELD_TOKEN => FieldType::SINGLE_LINE_TEXT,
self::FIELD_TOKEN_EXPIRES_AT => FieldType::DATETIME,
];

protected const FIELD_NAMES = [
...parent::FIELD_NAMES,
];
}

+ 48
- 0
app/Kintone/Models/CreditcardAutoPaymentInfo.php Bestand weergeven

@@ -0,0 +1,48 @@
<?php

namespace App\Kintone\Models;

use Illuminate\Support\Carbon;

/**
* アプリ名 クレジットカード自動課金情報
*
* @property string $customerCode 顧客コード
* @property string $customerName 顧客名
* @property string $autoPaymentNo 自動課金番号
* @property string $shopOrderNo 店舗側オーダー番号
* @property string $paymentInterval 課金周期
* @property int $paymentAmount 課金金額
* @property ?string $dataResult 受信電文
*/
class CreditcardAutoPaymentInfo extends KintoneModel
{
const CONFIG_KEY = "KINTONE_APP_CREDITCARD_AUTO_PAYMENT_INFO";

const FIELD_CUSTOMER_CODE = "顧客コード";
const FIELD_CUSTOMER_NAME = "顧客名";
const FIELD_AUTO_PAYMENT_NO = "自動課金番号";
const FIELD_SHOP_ORDER_NO = "店舗側オーダー番号";
const FIELD_PAYMENT_INTERVAL = "課金周期";
const FIELD_PAYMENT_AMOUNT = "課金金額";
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_AUTO_PAYMENT_NO => FieldType::SINGLE_LINE_TEXT,
self::FIELD_SHOP_ORDER_NO => FieldType::SINGLE_LINE_TEXT,
self::FIELD_PAYMENT_INTERVAL => FieldType::DROP_DOWN,
self::FIELD_PAYMENT_AMOUNT => FieldType::NUMBER,
self::FIELD_DATA_RESULT => FieldType::MULTI_LINE_TEXT,
];

protected const FIELD_NAMES = [
...parent::FIELD_NAMES,
];

protected const RELATIONS = [
Customer::class,
];
}

+ 57
- 0
app/Kintone/Models/CreditcardAutoPaymentResult.php Bestand weergeven

@@ -0,0 +1,57 @@
<?php

namespace App\Kintone\Models;

use Illuminate\Support\Carbon;

/**
* アプリ名 クレジットカード支払結果
*
* @property string $creditcardAutoPaymentNo クレジットカード自動課金番号
* @property string $customerCode 顧客コード
* @property string $customerName 顧客名
* @property string $paymentNo 決済番号
* @property Carbon $paymentDate 決済日
* @property string $paymentResult 決済結果
* @property ?string $errorCode エラーコード
* @property int $paymentAmount 課金金額
* @property string[] $poolDone プール済み
* @property ?string $dataResult 受信電文
*/
class CreditcardAutoPaymentResult extends KintoneModel
{
const CONFIG_KEY = "KINTONE_APP_CREDITCARD_AUTO_PAYMENT_RESULT";

const FIELD_CREDITCARD_AUTO_PAYMENT_NO = "クレジットカード自動課金番号";
const FIELD_CUSTOMER_CODE = "顧客コード";
const FIELD_CUSTOMER_NAME = "顧客名";
const FIELD_PAYMENT_NO = "決済番号";
const FIELD_PAYMENT_DATE = "決済日";
const FIELD_PAYMENT_RESULT = "決済結果";
const FIELD_ERROR_CODE = "エラーコード";
const FIELD_PAYMENT_AMOUNT = "課金金額";
const FIELD_POOL_DONE = "プール済み";
const FIELD_DATA_RESULT = "受信電文";

protected const FIELDS = [
...parent::FIELDS,
self::FIELD_CREDITCARD_AUTO_PAYMENT_NO => FieldType::SINGLE_LINE_TEXT,
self::FIELD_CUSTOMER_CODE => FieldType::NUMBER,
self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT,
self::FIELD_PAYMENT_NO => FieldType::SINGLE_LINE_TEXT,
self::FIELD_PAYMENT_DATE => FieldType::DATE,
self::FIELD_PAYMENT_RESULT => FieldType::DROP_DOWN,
self::FIELD_ERROR_CODE => FieldType::SINGLE_LINE_TEXT,
self::FIELD_PAYMENT_AMOUNT => FieldType::NUMBER,
self::FIELD_POOL_DONE => FieldType::CHECK_BOX,
self::FIELD_DATA_RESULT => FieldType::MULTI_LINE_TEXT,
];

protected const FIELD_NAMES = [
...parent::FIELD_NAMES,
];

protected const RELATIONS = [
CreditcardAutoPaymentInfo::class,
];
}

+ 33
- 0
app/Kintone/Models/Customer.php Bestand weergeven

@@ -2,6 +2,7 @@

namespace App\Kintone\Models;

use App\Kintone\Repositories\SeasonTicketContractRepository;
use Illuminate\Support\Facades\Auth;

/**
@@ -9,6 +10,7 @@ use Illuminate\Support\Facades\Auth;
* @property int customerCode
* @property string customerName
* @property string customerNameKana
* @property string paymentMethod
* @property string email
* @property string phoneNumber
* @property string zipCode
@@ -24,6 +26,7 @@ class Customer extends KintoneModel
const FIELD_CUSTOMER_CODE = "CustomerCode";
const FIELD_CUSTOMER_NAME = "CustomerName";
const FIELD_CUSTOMER_NAME_KANA = "顧客名カナ";
const FIELD_PAYMENT_METHOD = "支払方法";
const FIELD_EMAIL = "メールアドレス";
const FIELD_PHONE_NUMBER = "電話番号";
const FIELD_ZIP_CODE = "契約者_郵便番号";
@@ -37,6 +40,7 @@ class Customer extends KintoneModel
self::FIELD_CUSTOMER_CODE => FieldType::NUMBER,
self::FIELD_CUSTOMER_NAME => FieldType::SINGLE_LINE_TEXT,
self::FIELD_CUSTOMER_NAME_KANA => FieldType::SINGLE_LINE_TEXT,
self::FIELD_PAYMENT_METHOD => FieldType::SINGLE_LINE_TEXT,
self::FIELD_EMAIL => FieldType::LINK,
self::FIELD_PHONE_NUMBER => FieldType::LINK,
self::FIELD_ZIP_CODE => FieldType::SINGLE_LINE_TEXT,
@@ -57,6 +61,9 @@ class Customer extends KintoneModel
self::FIELD_PHONE_NUMBER => 'phone_no',
];

// キャッシュ
private bool|null $canPayByCreditcard = null;

public static function getSelf(): static
{
return static::getAccess()->find(Auth::user()->kintone_id);
@@ -71,6 +78,8 @@ class Customer extends KintoneModel
{
return [
'customer_name_kana_hankaku' => mb_convert_kana($this->customerNameKana, "sk"),
'can_pay_by_creditcard' => $this->canPayByCreditcard(),
'can_apply_to_change_payment_method_creditcard' => $this->canApplyToChangePaymentMethodCreditcard(),
];
}

@@ -78,4 +87,28 @@ class Customer extends KintoneModel
{
return !!$this->icSeasonTicektUserId;
}

public function canPayByCreditcard(bool $refresh = false): bool
{
// キャッシュがあればそれを返却する
if (is_bool($this->canPayByCreditcard) && $refresh === false) {
return $this->canPayByCreditcard;
}

$list = SeasonTicketContractRepository::get($this->customerCode);
foreach ($list as $ele) {
if (!$ele->plan->canPayByCreditcard()) {
$this->canPayByCreditcard = false;
return $this->canPayByCreditcard;
}
}
$this->canPayByCreditcard = true;
return $this->canPayByCreditcard;
}

// クレジットカード登録申請可否
public function canApplyToChangePaymentMethodCreditcard()
{
return $this->paymentMethod !== "クレジット" && $this->canPayByCreditcard();
}
}

+ 1
- 0
app/Kintone/Models/DropDown/PoolTransferHistory/TransferMethod.php Bestand weergeven

@@ -8,4 +8,5 @@ abstract class TransferMethod
const YUCHO = "ゆうちょ振込";
const CVS = "コンビニ支払";
const BANK_CHECK = "バンクチェック";
const CREDITCARD = "クレジットカード";
}

+ 4
- 0
app/Kintone/Models/PoolTransferHistory.php Bestand weergeven

@@ -20,6 +20,7 @@ use Illuminate\Support\Carbon;
* @property ?int incomeYuchoTransferRecordNo
* @property ?int incomeCvsPaymentRecordNo
* @property ?int incomeBankCheckPaymentRecordNo
* @property ?int incomeCreditcardPaymentRecordNo
* @property ?int paymentPlanRecordNo
* @property ?int seasonContractRecordNo
*/
@@ -40,6 +41,7 @@ class PoolTransferHistory extends KintoneModel
const FIELD_INCOME_YUCHO_TRANSFER_RECORD_NO = "ゆうちょ振込レコード番号";
const FIELD_INCOME_CVS_PAYMENT_RECORD_NO = "コンビニ支払レコード番号";
const FIELD_INCOME_BANK_CHECK_PAYMENT_RECORD_NO = "バンクチェック支払レコード番号";
const FIELD_INCOME_CREDITCARD_PAYMENT_RECORD_NO = "クレジットカード支払レコード番号";
const FIELD_PAYMENT_PLAN_RECORD_NO = "入金予定結果レコード番号";
const FIELD_SEASON_CONTRACT_RECORD_NO = "車室情報管理レコード番号";

@@ -59,6 +61,7 @@ class PoolTransferHistory extends KintoneModel
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_INCOME_CREDITCARD_PAYMENT_RECORD_NO => FieldType::NUMBER,
self::FIELD_PAYMENT_PLAN_RECORD_NO => FieldType::NUMBER,
self::FIELD_SEASON_CONTRACT_RECORD_NO => FieldType::NUMBER,
];
@@ -75,5 +78,6 @@ class PoolTransferHistory extends KintoneModel
Pool::class,
PaymentPlan::class,
BankCheckResult::class,
CreditcardAutoPaymentResult::class,
];
}

+ 10
- 0
app/Kintone/Models/SeasonTicketContractPlan.php Bestand weergeven

@@ -12,6 +12,7 @@ use Illuminate\Support\Collection;
* @property string parkingName
* @property string[] sendItem
* @property string vehicleType
* @property ?int amount
* @property ?int taxAmount
* @property ?int taxRate
* @property Collection<int ,CanChangePlanName> canChangePlanNameList
@@ -19,6 +20,7 @@ use Illuminate\Support\Collection;
* @property ?int chainGateDeposit
* @property ?int cardDeposit
* @property ?int totalDeposit
* @property string[] canPayByCreditcard
*/
class SeasonTicketContractPlan extends KintoneModel
{
@@ -29,12 +31,14 @@ class SeasonTicketContractPlan extends KintoneModel
const FIELD_PARKING_NAME = "定期_駐車場名";
const FIELD_SEND_ITEM = "送付物";
const FIELD_VEHICLE_TYPE = "種別";
const FIELD_AMOUNT = "契約金額";
const FIELD_TAX_AMOUNT = "内税";
const FIELD_TAX_RATE = "税率";
const FIELD_DEPOSIT = "保証金";
const FIELD_CHAIN_GATE_DEPOSIT = "チェーンゲート保証金";
const FIELD_CARD_DEPOSIT = "パスカード保証金";
const FIELD_TOTAL_DEPOSIT = "保証金合計額";
const FIELD_CAN_PAY_BY_CREDITCARD = "クレジットカード支払許可";

const FIELD_CAN_CHANGE_PLAN_NAME_LIST = "プラン変更申請にて変更可能なプラン一覧";
const FIELD_CAN_CHANGE_PLAN_NAME_LIST_PLAN_NAME = "プラン変更申請にて変更可能なプラン一覧_定期_駐車場名_月額金額_駐車場備考_プラン_種別_支払パターン";
@@ -46,11 +50,13 @@ class SeasonTicketContractPlan extends KintoneModel
self::FIELD_PARKING_NAME => FieldType::SINGLE_LINE_TEXT,
self::FIELD_SEND_ITEM => FieldType::CHECK_BOX,
self::FIELD_VEHICLE_TYPE => FieldType::SINGLE_LINE_TEXT,
self::FIELD_AMOUNT => FieldType::NUMBER,
self::FIELD_TAX_AMOUNT => FieldType::NUMBER,
self::FIELD_TAX_RATE => FieldType::NUMBER,
self::FIELD_CAN_CHANGE_PLAN_NAME_LIST => FieldType::SUBTABLE,
self::FIELD_DEPOSIT => FieldType::NUMBER,
self::FIELD_CHAIN_GATE_DEPOSIT => FieldType::NUMBER,
self::FIELD_CAN_PAY_BY_CREDITCARD => FieldType::CHECK_BOX,
self::FIELD_CARD_DEPOSIT => FieldType::NUMBER,
self::FIELD_TOTAL_DEPOSIT => FieldType::NUMBER,
];
@@ -89,4 +95,8 @@ class SeasonTicketContractPlan extends KintoneModel
{
return $this->canChangePlanNameList->isNotEmpty();
}
public function canPayByCreditcard(): bool
{
return in_array("許可", $this->canPayByCreditcard, true);
}
}

+ 9
- 0
app/Logic/GeneralApplicationManager.php Bestand weergeven

@@ -4,6 +4,7 @@ namespace App\Logic;

use App\Exceptions\AppCommonException;
use App\Kintone\Models\BankAccountUpdateApplication;
use App\Kintone\Models\ChangePaymentMethodCreditcardOrderApplication;
use App\Kintone\Models\ChangePlanApplication;
use App\Kintone\Models\Customer;
use App\Kintone\Models\GeneralApplication;
@@ -76,6 +77,14 @@ class GeneralApplicationManager
$this->setType("プラン変更");
return;
}
if ($model instanceof ParkingUseTypeChangeOrderApplication) {
$this->setType("IC定期_駐車場利用方法変更申請");
return;
}
if ($model instanceof ChangePaymentMethodCreditcardOrderApplication) {
$this->setType("クレジット支払変更申請");
return;
}
}

public function setCustomer(Customer $customer): static


+ 7
- 2
app/Logic/PoolTransferManager.php Bestand weergeven

@@ -4,6 +4,7 @@ namespace App\Logic;

use App\Exceptions\SkipException;
use App\Kintone\Models\BankCheckResult;
use App\Kintone\Models\CreditcardAutoPaymentResult;
use App\Kintone\Models\DropDown\PoolTransferHistory\TransferMethod;
use App\Kintone\Models\DropDown\PoolTransferHistory\TransgerType;
use App\Kintone\Models\Pool;
@@ -19,12 +20,12 @@ use App\Util\DateUtil;
class PoolTransferManager
{

private SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult|null $payment = null;
private SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult|CreditcardAutoPaymentResult|null $payment = null;
private Pool|null $pool = null;
private PoolTransferHistory|null $history = null;


public function moveToPool(SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult $payment): Pool
public function moveToPool(SmbcPayment|SmbcAccountTransferResult|YuchoPaymentResult|BankCheckResult|CreditcardAutoPaymentResult $payment): Pool
{
$this->clear();

@@ -94,6 +95,10 @@ class PoolTransferManager
$history->incomeMethod = TransferMethod::BANK_CHECK;
$history->incomeBankCheckPaymentRecordNo = $this->payment->getRecordId();
}
if ($this->payment instanceof CreditcardAutoPaymentResult) {
$history->incomeMethod = TransferMethod::CREDITCARD;
$history->incomeCreditcardPaymentRecordNo = $this->payment->getRecordId();
}

$this->history = $history;
}


+ 3
- 0
routes/api.php Bestand weergeven

@@ -50,7 +50,10 @@ RouteHelper::post('/ask', App\Http\Controllers\Web\FAQ\AskController::class);
RouteHelper::post('/email/change/start', App\Http\Controllers\Web\Customer\ChangeEmailStartController::class);
RouteHelper::post('/email/change/verify', App\Http\Controllers\Web\Customer\ChangeEmailVerifyController::class);
RouteHelper::post('/customer/update-info-order', App\Http\Controllers\Web\Customer\UpdateUserInfoOrderController::class);
RouteHelper::post('/customer/change-payment-method-creditcard-order', App\Http\Controllers\Web\Customer\ChangePaymentMethodCreditcardOrderController::class);
RouteHelper::get('/customer/bank-account-register/start', App\Http\Controllers\Web\Customer\BankAccountRegisterStartController::class);

RouteHelper::post('/password/setting/start', App\Http\Controllers\Web\Auth\PasswordSettingStartController::class);
RouteHelper::post('/password/setting/verify', App\Http\Controllers\Web\Auth\PasswordSettingVerifyController::class);

RouteHelper::post('/robot-payment/creditcard/token/check', App\Http\Controllers\Web\RobotPayment\CreditCard\RegisterTokenCheckController::class);

+ 5
- 2
routes/web.php Bestand weergeven

@@ -22,8 +22,11 @@ RouteHelper::get('/image/season-ticket-contract/{id}', App\Http\Controllers\Web\

// ロボットペイメント画面遷移
RouteHelper::get('/robot-payment/bank-check/register', App\Http\Controllers\Web\RobotPayment\BanckCheck\RegisterController::class);
// BANK CHECK WEBHOOK
RouteHelper::get('/robot-payment/bank-check/info', App\Http\Controllers\Web\RobotPayment\BanckCheck\PaymentInfoController::class);
RouteHelper::get('/robot-payment/creditcard/register/test', App\Http\Controllers\Web\RobotPayment\CreditCard\RegisterTestController::class);
// ロボットペイメント WEBHOOK 決済通知
RouteHelper::get('/robot-payment/payment-info', App\Http\Controllers\Web\RobotPayment\PaymentInfoIndexController::class);
// ロボットペイメント WEBHOOK 自動課金通知
RouteHelper::get('/robot-payment/creditcard/auto-payment-info', App\Http\Controllers\Web\RobotPayment\CreditCard\PaymentResultController::class);


// ルーティングで適合しない場合はフロント側のRoutingにゆだねる


Laden…
Annuleren
Opslaan