-
-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: CryptoBot payments #940
base: development
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,117 @@ | ||||||
<?php | ||||||
|
||||||
namespace App\Extensions\PaymentGateways\CryptoBot; | ||||||
|
||||||
use App\Classes\AbstractExtension; | ||||||
use App\Enums\PaymentStatus; | ||||||
use App\Events\PaymentEvent; | ||||||
use App\Events\UserUpdateCreditsEvent; | ||||||
use App\Models\PartnerDiscount; | ||||||
use App\Models\Payment; | ||||||
use App\Models\ShopProduct; | ||||||
use App\Models\User; | ||||||
use App\Models\Coupon; | ||||||
use App\Traits\Coupon as CouponTrait; | ||||||
use App\Events\CouponUsedEvent; | ||||||
use Exception; | ||||||
use Illuminate\Http\JsonResponse; | ||||||
use Illuminate\Http\Request; | ||||||
use Illuminate\Support\Facades\Auth; | ||||||
use Illuminate\Support\Facades\Redirect; | ||||||
use Illuminate\Support\Facades\Log; | ||||||
use Illuminate\Support\Facades\Http; | ||||||
use App\Notifications\ConfirmPaymentNotification; | ||||||
|
||||||
/** | ||||||
* Summary of PayPalExtension | ||||||
*/ | ||||||
class CryptoBotExtension extends AbstractExtension | ||||||
{ | ||||||
use CouponTrait; | ||||||
|
||||||
public static function getConfig(): array | ||||||
{ | ||||||
return [ | ||||||
"name" => "CryptoBot", | ||||||
"RoutesIgnoreCsrf" => [ | ||||||
"payment/CryptoBotWebhook" | ||||||
], | ||||||
]; | ||||||
} | ||||||
|
||||||
public static function getRedirectUrl(Payment $payment, ShopProduct $shopProduct, string $totalPriceString): string | ||||||
{ | ||||||
$url = 'https://pay.crypt.bot/api/createInvoice'; | ||||||
$settings = new CryptoBotSettings(); | ||||||
try { | ||||||
$response = Http::withHeaders([ | ||||||
'Accept' => 'application/json', | ||||||
'Content-Type' => 'application/json', | ||||||
'Crypto-Pay-API-Token' => $settings->api_key | ||||||
])->post($url, [ | ||||||
'amount' => $totalPriceString, | ||||||
'payload' => strval($payment->id), | ||||||
'description' => "Заказ #{$payment->id} - " . $shopProduct->name, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace Заказ with Order
Suggested change
|
||||||
'currency_type' => 'fiat', | ||||||
'fiat' => $shopProduct->currency_code, | ||||||
'hidden_message' => $settings->hidden_message, | ||||||
'paid_btn_name' => 'callback', | ||||||
'paid_btn_url' => route('payment.CryptoBotSuccess').'?payment=YGqvOf4I' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not quite sure if it's correct, can you double-check this part of the code? To be more precise, this -> |
||||||
]); | ||||||
|
||||||
if($response->json('ok') == false){ | ||||||
return $response->json('error.name'); | ||||||
} | ||||||
|
||||||
return $response->json('result.pay_url'); | ||||||
} catch (Exception $ex) { | ||||||
Log::error('CryptoBot Payment: ' . $ex->getMessage()); | ||||||
throw new Exception('Payment failed'); | ||||||
} | ||||||
} | ||||||
|
||||||
static function success(Request $request): void | ||||||
{ | ||||||
Redirect::route('home')->with('success', 'Your payment is processing')->send(); | ||||||
return; | ||||||
} | ||||||
|
||||||
static function webhook(Request $request): JsonResponse | ||||||
{ | ||||||
|
||||||
$settings = new CryptoBotSettings(); | ||||||
/*** Проверка подписи ***/ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also translate this comment into English
Suggested change
|
||||||
$sign_header = $request->header('crypto-pay-api-signature'); | ||||||
|
||||||
$secret_key = hash('sha256', $settings->api_key, true); | ||||||
$calculated_signature = hash_hmac('sha256', $request->getContent(), $secret_key); | ||||||
|
||||||
if (!hash_equals($sign_header, $calculated_signature)) { | ||||||
return response()->json(['status' => 'invalid sign.']); | ||||||
} | ||||||
/*** ***/ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't forget to delete unused lines of code (Even comments)
Suggested change
|
||||||
|
||||||
$payment = Payment::findOrFail($request->json('payload.payload')); | ||||||
$shopProduct = ShopProduct::findOrFail($payment->shop_item_product_id); | ||||||
$user = User::findOrFail($payment->user_id); | ||||||
|
||||||
//update payment | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep the style of writing the code, if you used a different type of comment formatting above, then save it to the end of the file
Suggested change
|
||||||
$payment->update([ | ||||||
'status' => PaymentStatus::PAID, | ||||||
'payment_id' => $request->input('payload.invoice_id'), | ||||||
]); | ||||||
try { | ||||||
$user->increment('credits', $payment->amount); | ||||||
} catch (Exception $exception) { | ||||||
throw $exception; | ||||||
} | ||||||
|
||||||
|
||||||
event(new PaymentEvent($user, $payment, $shopProduct)); | ||||||
event(new UserUpdateCreditsEvent($user)); | ||||||
$user->notify(new ConfirmPaymentNotification($payment)); | ||||||
|
||||||
// return a 200 status code | ||||||
return response()->json(['success' => true]); | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
namespace App\Extensions\PaymentGateways\CryptoBot; | ||
|
||
use Spatie\LaravelSettings\Settings; | ||
|
||
class CryptoBotSettings extends Settings | ||
{ | ||
|
||
public bool $enabled = false; | ||
public ?string $api_key; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you set the api_key as encrypted in the migration it needs to be markes as encrypted in here too: |
||
|
||
public static function group(): string | ||
{ | ||
return 'cryptobot'; | ||
} | ||
|
||
|
||
|
||
public static function getOptionInputData() | ||
{ | ||
return [ | ||
'category_icon' => 'fas fa-dollar-sign', | ||
'api_key' => [ | ||
'type' => 'string', | ||
'label' => 'API Key', | ||
'description' => 'The API Key of your CryptoPay app', | ||
], | ||
'hidden_message' => [ | ||
'type' => 'string', | ||
'label' => 'Hidden Message', | ||
'description' => 'Message displayed after payment', | ||
], | ||
'enabled' => [ | ||
'type' => 'boolean', | ||
'label' => 'Enabled', | ||
'description' => 'Enable or disable this payment gateway', | ||
], | ||
]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
use Spatie\LaravelSettings\Migrations\SettingsMigration; | ||
|
||
class CreateCryptoBotSettings extends SettingsMigration | ||
{ | ||
public function up(): void | ||
{ | ||
$this->migrator->addEncrypted('cryptobot.api_key', null); | ||
$this->migrator->addEncrypted('cryptobot.hidden_message', null); | ||
$this->migrator->add('cryptobot.enabled', false); | ||
} | ||
|
||
public function down(): void | ||
{ | ||
$this->migrator->delete('cryptobot.api_key'); | ||
$this->migrator->delete('cryptobot.hidden_message'); | ||
$this->migrator->delete('cryptobot.enabled'); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
use Illuminate\Support\Facades\Route; | ||
use App\Extensions\PaymentGateways\CryptoBot\CryptoBotExtension; | ||
|
||
Route::middleware(['web', 'auth'])->group(function () { | ||
Route::get( | ||
'payment/CryptoBotSuccess', | ||
function () { | ||
CryptoBotExtension::success(request()); | ||
} | ||
)->name('payment.CryptoBotSuccess'); | ||
}); | ||
|
||
|
||
Route::post('payment/CryptoBotWebhook', function () { | ||
CryptoBotExtension::webhook(request()); | ||
})->name('payment.CryptoBotWebhook'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change or remove this comment