digipay
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
- 2026-09-16 | تعداد کد هدیه | `GiftCardController::redeem` | count=N → یک رکورد giftcards با count=N + N ردیف giftcard_codes؛ مثل storeRedeem
|
||||
- 2026-09-12 | انقضای کارت هدیه | `GiftCardController::validateGiftExpiryDate` + `GiftCardEditorFormBody` | تاریخ قبل از امروز → ۴۰۰ / خطای فرم؛ امروز مجاز
|
||||
- 2026-09-09 | رمز ادمین ≠ لاگین اپ | `Customer::setPasswordAttribute` + `AuthController` + `updateAdmin` | قبل از هش/لاگین ارقام فارسی→انگلیسی؛ jwt hash=false؛ آنلاین فقط password غیرخالی بفرست
|
||||
- 2026-10-20 | خرید اقساطی دیجیپی | `DigipayInstallmentService` + جداول `digipay_credits`/`digipay_orders` + migration `2026_10_20_000002` | فلگ پیشفرض خاموش؛ اعتبار را ادمین ست میکند نه وبهوک دیجیپی
|
||||
- 2026-10-20 | دسترسی صفحات مدیر | `users.page_access` + `AdminPageAccess` + ادمین `adminPageAccess.ts` / ویرایش مدیران | null=کامل؛ درخت مشاهده/ویرایش/حذف؛ ورود=اولین صفحه مجاز؛ منوی ممنوع=«شما به این صفحه دسترسی ندارید»
|
||||
- 2026-10-20 | ویرایش/حذف کارت هدیه | `GiftCardController::update/destroy` + `giftCards/components/table.vue` | PUT/DELETE `/admin/giftcard/{id}`؛ کارت استفادهشده حذف نمیشود و مقدار/تعدادش عوض نمیشود
|
||||
- 2026-10-20 | دکمه ویرایش/حذف گیفت | `allowsPageFlag` + `giftCards/components/table.vue` | بدون edit/delete روی giftCardMain دکمه و دیالوگ باز نمیشود
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\DigipayInstallmentService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DigipayInstallmentController extends Controller
|
||||
{
|
||||
public function __construct(private DigipayInstallmentService $service)
|
||||
{
|
||||
}
|
||||
|
||||
public function setCredit(Request $request)
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
$data = $request->validate([
|
||||
'mobile' => 'required|string|max:20',
|
||||
'plan4_toman' => 'required|integer|min:0',
|
||||
'plan12_toman' => 'required|integer|min:0',
|
||||
]);
|
||||
|
||||
return response()->json($this->service->setCredit(
|
||||
$data['mobile'],
|
||||
(int) $data['plan4_toman'],
|
||||
(int) $data['plan12_toman']
|
||||
));
|
||||
}
|
||||
|
||||
public function orders()
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
|
||||
return response()->json(['data' => $this->service->recentOrders()]);
|
||||
}
|
||||
|
||||
private function ensureEnabled(): void
|
||||
{
|
||||
if (! $this->service->enabled()) {
|
||||
abort(403, 'خرید اقساطی فعال نیست');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Customer;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\DigipayInstallmentService;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DigipayInstallmentController extends Controller
|
||||
{
|
||||
public function __construct(private DigipayInstallmentService $service)
|
||||
{
|
||||
}
|
||||
|
||||
public function show()
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
|
||||
return response()->json($this->service->statusFor((int) auth('customer')->id()));
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
$this->service->markStarted((int) auth('customer')->id());
|
||||
|
||||
return response()->json($this->service->statusFor((int) auth('customer')->id()));
|
||||
}
|
||||
|
||||
public function buy(Request $request)
|
||||
{
|
||||
$this->ensureEnabled();
|
||||
$data = $request->validate([
|
||||
'plan' => 'required|integer|in:4,12',
|
||||
'amount_toman' => 'required|integer|min:1000',
|
||||
]);
|
||||
|
||||
$result = $this->service->buy(
|
||||
(int) auth('customer')->id(),
|
||||
(int) $data['plan'],
|
||||
(int) $data['amount_toman']
|
||||
);
|
||||
|
||||
return response()->json($result);
|
||||
}
|
||||
|
||||
private function ensureEnabled(): void
|
||||
{
|
||||
if (! $this->service->enabled()) {
|
||||
abort(403, 'خرید اقساطی فعال نیست');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ class AdminPageAccess
|
||||
'customerMain_online',
|
||||
'customerMain_specialPrice',
|
||||
'customerMain_goldCredit',
|
||||
'customerMain_digipayInstallment',
|
||||
'productsMain_limitedOrder',
|
||||
'productsMain_archive',
|
||||
'productsMain_categories',
|
||||
@@ -62,6 +63,7 @@ class AdminPageAccess
|
||||
'customerMain_archive' => ['restore', 'info'],
|
||||
'customerMain_specialPrice' => ['edit', 'toggle', 'delete'],
|
||||
'customerMain_goldCredit' => ['detail', 'edit', 'approve', 'reject'],
|
||||
'customerMain_digipayInstallment' => ['edit'],
|
||||
'productsMain_limitedOrder' => ['buy', 'sell', 'list', 'tv', 'edit', 'archive'],
|
||||
'productsMain_archive' => ['restore', 'info'],
|
||||
'ordersMain' => ['info'],
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Customer;
|
||||
use App\Models\Price;
|
||||
use App\Models\Withdraw;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Rooyesh\Wallet\interfaces\TransactionInterface;
|
||||
use Rooyesh\Wallet\interfaces\WalletInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
class DigipayInstallmentService
|
||||
{
|
||||
public function enabled(): bool
|
||||
{
|
||||
return app(ConfigService::class)->getBool('enable_digipay_installment', false);
|
||||
}
|
||||
|
||||
public function publicConfig(): array
|
||||
{
|
||||
$cfg = app(ConfigService::class);
|
||||
|
||||
return [
|
||||
'onboarding_url' => trim($cfg->getString('digipay_onboarding_url', '')),
|
||||
'fee_shop_percent' => (float) $cfg->getString('digipay_fee_shop_percent', '8'),
|
||||
'fee_gateway_percent' => (float) $cfg->getString('digipay_fee_gateway_percent', '5.7'),
|
||||
'fee_extra_percent' => (float) $cfg->getString('digipay_fee_extra_percent', '2.3'),
|
||||
'plan4_cap_toman' => (int) $cfg->getString('digipay_plan4_cap_toman', '30000000'),
|
||||
'plan12_cap_toman' => (int) $cfg->getString('digipay_plan12_cap_toman', '200000000'),
|
||||
];
|
||||
}
|
||||
|
||||
public function statusFor(int $customerId): array
|
||||
{
|
||||
$credit = DB::table('digipay_credits')->where('customer_id', $customerId)->first();
|
||||
$config = $this->publicConfig();
|
||||
|
||||
return [
|
||||
'enabled' => true,
|
||||
'status' => $credit->status ?? 'none',
|
||||
'plan4_remaining_toman' => (int) floor(((int) ($credit->plan4_remaining_rial ?? 0)) / 10),
|
||||
'plan12_remaining_toman' => (int) floor(((int) ($credit->plan12_remaining_rial ?? 0)) / 10),
|
||||
'gram_price_rial' => $this->gramPriceRial(),
|
||||
'config' => $config,
|
||||
];
|
||||
}
|
||||
|
||||
public function markStarted(int $customerId): void
|
||||
{
|
||||
$config = $this->publicConfig();
|
||||
if ($config['onboarding_url'] === '') {
|
||||
throw new UnprocessableEntityHttpException('لینک دیجیپی در تنظیمات ثبت نشده است');
|
||||
}
|
||||
|
||||
$existing = DB::table('digipay_credits')->where('customer_id', $customerId)->first();
|
||||
if ($existing && $existing->status === 'active') {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($existing) {
|
||||
DB::table('digipay_credits')->where('id', $existing->id)->update([
|
||||
'status' => 'pending',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
DB::table('digipay_credits')->insert([
|
||||
'customer_id' => $customerId,
|
||||
'status' => 'pending',
|
||||
'plan4_remaining_rial' => 0,
|
||||
'plan12_remaining_rial' => 0,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function setCredit(string $mobile, int $plan4Toman, int $plan12Toman): array
|
||||
{
|
||||
$customer = Customer::findActiveByMobile($mobile);
|
||||
if (! $customer) {
|
||||
throw new UnprocessableEntityHttpException('مشتری با این موبایل پیدا نشد');
|
||||
}
|
||||
|
||||
$row = [
|
||||
'status' => 'active',
|
||||
'plan4_remaining_rial' => max(0, $plan4Toman) * 10,
|
||||
'plan12_remaining_rial' => max(0, $plan12Toman) * 10,
|
||||
'updated_at' => now(),
|
||||
];
|
||||
|
||||
$existing = DB::table('digipay_credits')->where('customer_id', $customer->id)->first();
|
||||
if ($existing) {
|
||||
DB::table('digipay_credits')->where('id', $existing->id)->update($row);
|
||||
} else {
|
||||
$row['customer_id'] = $customer->id;
|
||||
$row['created_at'] = now();
|
||||
DB::table('digipay_credits')->insert($row);
|
||||
}
|
||||
|
||||
return [
|
||||
'customer_id' => (int) $customer->id,
|
||||
'name' => $customer->name,
|
||||
'plan4_remaining_toman' => max(0, $plan4Toman),
|
||||
'plan12_remaining_toman' => max(0, $plan12Toman),
|
||||
];
|
||||
}
|
||||
|
||||
public function buy(int $customerId, int $plan, int $amountToman): array
|
||||
{
|
||||
if (! in_array($plan, [4, 12], true)) {
|
||||
throw new UnprocessableEntityHttpException('طرح اقساط نامعتبر است');
|
||||
}
|
||||
if ($amountToman < 1000) {
|
||||
throw new UnprocessableEntityHttpException('مبلغ خرید را وارد کنید');
|
||||
}
|
||||
|
||||
$price = $this->gramPriceRial();
|
||||
if ($price <= 0) {
|
||||
throw new UnprocessableEntityHttpException('قیمت لحظهای در دسترس نیست');
|
||||
}
|
||||
|
||||
$config = $this->publicConfig();
|
||||
$cap = $plan === 4 ? $config['plan4_cap_toman'] : $config['plan12_cap_toman'];
|
||||
if ($amountToman > $cap) {
|
||||
throw new UnprocessableEntityHttpException('مبلغ از سقف این طرح بیشتر است');
|
||||
}
|
||||
|
||||
$feePercent = $config['fee_shop_percent'] + $config['fee_gateway_percent'] + $config['fee_extra_percent'];
|
||||
$amountRial = $amountToman * 10;
|
||||
$chargeRial = (int) round($amountRial * (1 + ($feePercent / 100)));
|
||||
$feeRial = $chargeRial - $amountRial;
|
||||
$grams = round($amountRial / $price, 4);
|
||||
if ($grams <= 0) {
|
||||
throw new UnprocessableEntityHttpException('مقدار مس محاسبهشده نامعتبر است');
|
||||
}
|
||||
|
||||
$column = $plan === 4 ? 'plan4_remaining_rial' : 'plan12_remaining_rial';
|
||||
|
||||
return DB::transaction(function () use ($customerId, $plan, $amountRial, $feeRial, $grams, $price, $chargeRial, $column) {
|
||||
$credit = DB::table('digipay_credits')->where('customer_id', $customerId)->lockForUpdate()->first();
|
||||
if (! $credit || $credit->status !== 'active') {
|
||||
throw new UnprocessableEntityHttpException('اعتبار اقساطی شما هنوز فعال نشده است');
|
||||
}
|
||||
if ((int) $credit->{$column} < $chargeRial) {
|
||||
throw new UnprocessableEntityHttpException('مانده اعتبار این طرح کافی نیست');
|
||||
}
|
||||
|
||||
DB::table('digipay_credits')->where('id', $credit->id)->update([
|
||||
$column => (int) $credit->{$column} - $chargeRial,
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$orderId = DB::table('digipay_orders')->insertGetId([
|
||||
'customer_id' => $customerId,
|
||||
'plan' => $plan,
|
||||
'amount_rial' => $amountRial,
|
||||
'fee_rial' => $feeRial,
|
||||
'grams' => $grams,
|
||||
'gram_price_rial' => $price,
|
||||
'status' => 'done',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$this->creditMetal($customerId, $grams, (int) $orderId);
|
||||
|
||||
return [
|
||||
'order_id' => (int) $orderId,
|
||||
'grams' => $grams,
|
||||
'plan' => $plan,
|
||||
'charge_toman' => (int) floor($chargeRial / 10),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function recentOrders(int $limit = 50): array
|
||||
{
|
||||
return DB::table('digipay_orders as o')
|
||||
->leftJoin('customers as c', 'c.id', '=', 'o.customer_id')
|
||||
->orderByDesc('o.id')
|
||||
->limit($limit)
|
||||
->get([
|
||||
'o.id',
|
||||
'o.customer_id',
|
||||
'c.name',
|
||||
'c.mobile',
|
||||
'o.plan',
|
||||
'o.amount_rial',
|
||||
'o.fee_rial',
|
||||
'o.grams',
|
||||
'o.created_at',
|
||||
])
|
||||
->map(function ($row) {
|
||||
return [
|
||||
'id' => (int) $row->id,
|
||||
'customer_id' => (int) $row->customer_id,
|
||||
'name' => $row->name,
|
||||
'mobile' => $row->mobile,
|
||||
'plan' => (int) $row->plan,
|
||||
'amount_toman' => (int) floor(((int) $row->amount_rial) / 10),
|
||||
'fee_toman' => (int) floor(((int) $row->fee_rial) / 10),
|
||||
'grams' => (float) $row->grams,
|
||||
'created_at' => $row->created_at,
|
||||
];
|
||||
})
|
||||
->all();
|
||||
}
|
||||
|
||||
private function gramPriceRial(): int
|
||||
{
|
||||
return (int) (Price::query()->orderByDesc('id')->value('price') ?? 0);
|
||||
}
|
||||
|
||||
private function creditMetal(int $customerId, float $grams, int $orderId): void
|
||||
{
|
||||
$user = Customer::query()->find($customerId);
|
||||
if (! $user) {
|
||||
throw new UnprocessableEntityHttpException('مشتری پیدا نشد');
|
||||
}
|
||||
|
||||
$withdraw = Withdraw::create([
|
||||
'customer_id' => $user->id,
|
||||
'gold' => $grams,
|
||||
'note' => 'خرید اقساطی',
|
||||
'sts' => 6,
|
||||
'tracked_number' => $orderId,
|
||||
]);
|
||||
|
||||
$wallet = new WalletInterface($user->id, $user->type);
|
||||
new TransactionInterface($wallet, [
|
||||
'cash' => 0,
|
||||
'gold' => $grams,
|
||||
'expire_at' => now(),
|
||||
'note' => 'خرید اقساطی',
|
||||
'withdraw_id' => $withdraw->id,
|
||||
'active' => true,
|
||||
], 7, true, false);
|
||||
|
||||
try {
|
||||
app(ShayeganSyncService::class)->recordWalletGold([
|
||||
'customer_id' => $user->id,
|
||||
'value' => $grams,
|
||||
'direction' => 1,
|
||||
'withdraw_id' => $withdraw->id,
|
||||
'note' => 'خرید اقساطی',
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
report($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable('digipay_credits')) {
|
||||
Schema::create('digipay_credits', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('customer_id')->unique();
|
||||
$table->string('status', 20)->default('pending');
|
||||
$table->unsignedBigInteger('plan4_remaining_rial')->default(0);
|
||||
$table->unsignedBigInteger('plan12_remaining_rial')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('digipay_orders')) {
|
||||
Schema::create('digipay_orders', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('customer_id')->index();
|
||||
$table->unsignedTinyInteger('plan');
|
||||
$table->unsignedBigInteger('amount_rial');
|
||||
$table->unsignedBigInteger('fee_rial');
|
||||
$table->decimal('grams', 16, 4);
|
||||
$table->unsignedBigInteger('gram_price_rial');
|
||||
$table->string('status', 20)->default('done');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
if (! Schema::hasTable('settings')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rows = [
|
||||
[
|
||||
'key' => 'enable_digipay_installment',
|
||||
'value' => 'false',
|
||||
'title_fa' => 'خرید اقساطی مس',
|
||||
'description' => 'روشن: منوی خرید اقساطی در اپ و صفحه اعتبار دیجیپی در ادمین.',
|
||||
'type' => 'switch',
|
||||
'show' => 1,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_onboarding_url',
|
||||
'value' => '',
|
||||
'title_fa' => 'لینک احراز دیجیپی',
|
||||
'description' => 'لینکی که دیجیپی بعد از قرارداد میدهد. کاربر برای احراز هویت به همین آدرس میرود.',
|
||||
'type' => 'text',
|
||||
'show' => 0,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_fee_shop_percent',
|
||||
'value' => '8',
|
||||
'title_fa' => 'کارمزد خرید اقساطی (درصد)',
|
||||
'description' => '',
|
||||
'type' => 'number',
|
||||
'show' => 1,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_fee_gateway_percent',
|
||||
'value' => '5.7',
|
||||
'title_fa' => 'کارمزد دیجیپی (درصد)',
|
||||
'description' => '',
|
||||
'type' => 'number',
|
||||
'show' => 1,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_fee_extra_percent',
|
||||
'value' => '2.3',
|
||||
'title_fa' => 'کارمزد جانبی اقساط (درصد)',
|
||||
'description' => '',
|
||||
'type' => 'number',
|
||||
'show' => 1,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_plan4_cap_toman',
|
||||
'value' => '30000000',
|
||||
'title_fa' => 'سقف اعتبار ۴ قسط (تومان)',
|
||||
'description' => '',
|
||||
'type' => 'number',
|
||||
'show' => 1,
|
||||
],
|
||||
[
|
||||
'key' => 'digipay_plan12_cap_toman',
|
||||
'value' => '200000000',
|
||||
'title_fa' => 'سقف وام ۱۲ قسط (تومان)',
|
||||
'description' => '',
|
||||
'type' => 'number',
|
||||
'show' => 1,
|
||||
],
|
||||
];
|
||||
|
||||
$hasType = Schema::hasColumn('settings', 'type');
|
||||
$hasShow = Schema::hasColumn('settings', 'show_to_user');
|
||||
|
||||
foreach ($rows as $row) {
|
||||
if (DB::table('settings')->where('key', $row['key'])->exists()) {
|
||||
continue;
|
||||
}
|
||||
$insert = [
|
||||
'key' => $row['key'],
|
||||
'value' => $row['value'],
|
||||
'title_fa' => $row['title_fa'],
|
||||
'description' => $row['description'],
|
||||
'can_edit' => 1,
|
||||
'is_active' => 1,
|
||||
];
|
||||
if ($hasType) {
|
||||
$insert['type'] = $row['type'];
|
||||
}
|
||||
if ($hasShow) {
|
||||
$insert['show_to_user'] = $row['show'];
|
||||
}
|
||||
DB::table('settings')->insert($insert);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('digipay_orders');
|
||||
Schema::dropIfExists('digipay_credits');
|
||||
}
|
||||
};
|
||||
@@ -23,6 +23,7 @@ use App\Http\Controllers\Admin\ShayeganController;
|
||||
use App\Http\Controllers\Admin\FileController;
|
||||
use App\Http\Controllers\Site\OfferCodesController;
|
||||
use App\Http\Controllers\Admin\SettingsController;
|
||||
use App\Http\Controllers\Admin\DigipayInstallmentController as AdminDigipayInstallmentController;
|
||||
use App\Http\Controllers\Admin\GoldCreditController as AdminGoldCreditController;
|
||||
use \App\Http\Controllers\Admin\GiftCardController;
|
||||
use App\Http\Controllers\Admin\CategoryController;
|
||||
@@ -184,6 +185,9 @@ Route::middleware(['auth:user', 'admin.page'])->group(function (){
|
||||
Route::put('/gold_credit/{id}', [AdminGoldCreditController::class, 'update']);
|
||||
Route::post('/gold_credit', [AdminGoldCreditController::class, 'store']);
|
||||
|
||||
Route::post('/digipay_installment/credit', [AdminDigipayInstallmentController::class, 'setCredit']);
|
||||
Route::post('/digipay_installment/orders', [AdminDigipayInstallmentController::class, 'orders']);
|
||||
|
||||
Route::post('/wallet/charge_wallet',[WalletController::class,'charge_wallet']);
|
||||
Route::get('/wallet/charge-targets',[WalletController::class,'chargeTargets']);
|
||||
Route::post('/wallet/table',[WalletController::class,'indexWallet']);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\Customer\CustomerController;
|
||||
use App\Http\Controllers\Customer\DigipayInstallmentController;
|
||||
use App\Http\Controllers\Customer\GoldCreditController;
|
||||
use App\Http\Controllers\Customer\OrderController;
|
||||
use App\Http\Controllers\Customer\AddressController;
|
||||
@@ -173,6 +174,10 @@ Route::middleware(['auth:customer', 'customer.active'])->group(function () use (
|
||||
Route::post('gold_credit/request', [GoldCreditController::class, 'requestLoan']);
|
||||
Route::post('gold_credit/installments/pay', [GoldCreditController::class, 'payInstallments']);
|
||||
|
||||
Route::get('digipay_installment', [DigipayInstallmentController::class, 'show']);
|
||||
Route::post('digipay_installment/start', [DigipayInstallmentController::class, 'start']);
|
||||
Route::post('digipay_installment/buy', [DigipayInstallmentController::class, 'buy']);
|
||||
|
||||
if ($isStore) {
|
||||
Route::post('vc_validate', [havaleController::class, 'virtualCardValidate']);
|
||||
Route::post('havale', [havaleController::class, 'havale']);
|
||||
|
||||
Reference in New Issue
Block a user