blade:
$( "#Pay_Crypto_ccpayment_btn" ).click(function() {
$('.btn-pay').prop('disabled', true);
// window.location.href = "/Pay-With-Crypto-ccpayment/{{$Invoice_ID}}/{{$Plan_ID}}";
window.location.replace("/Pay-With-Crypto-ccpayment/{{$Invoice_ID}}/{{$Plan_ID}}")
})
------------------------
web:
Route::get('/Pay-With-Crypto-ccpayment/{InvoiceID}/{Plan_ID}', [ccpayment_gateway_Controller::class , 'PayWithCrypto_ccpayment']);
Route::get('/getFiatList', [ccpayment_gateway_Controller::class , 'getFiatList']);
Route::get('/getCoinList', [ccpayment_gateway_Controller::class , 'getCoinList']);
Route::get('/getOrderInfo/{OrderID}', [ccpayment_gateway_Controller::class , 'getOrderInfo']);
Route::get('/getOrderInfo_ccpayment/{OrderID}', [ccpayment_gateway_Controller::class , 'getOrderInfo_ccpayment']);
Route::get('/getTotalPaid_ccpayment/{OrderID}', [ccpayment_gateway_Controller::class , 'getTotalPaid_ccpayment']);
------------------------------------------------
Controller:
<?php
namespace App\Http\Controllers;
use App\Models\authModel;
use App\Models\Invoice_Model;
use App\Models\invoice_unpaid_Model;
use App\Models\plan_Model;
use App\Models\site_settings_Model;
use App\Models\use_proxy_Model;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;
use MarcialPaulG\Coinbase\Exceptions\InvalidRequestException;
use MarcialPaulG\Coinbase\Exceptions\RateLimitExceededException;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class ccpayment_gateway_Controller extends Controller
{
// get Total Paid
public function getTotalPaid_ccpayment($orderId)
{
$orderInfo = $this->getOrderInfo_ccpayment($orderId);
$totalPaid = 0;
foreach ($orderInfo['paidList'] ?? [] as $record) {
if ($record['status'] === 'Success') {
$totalPaid += floatval($record['amount']);
}
}
return $totalPaid;
}
// get Order Info all
public function getOrderInfo_ccpayment($orderId)
{
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$url = "https://ccpayment.com/ccpayment/v2/getAppOrderInfo"; // ⚠️ dashboard-এ path মিলিয়ে নিন
$content = [
"orderId" => $orderId, // merchant_order_id, যেটা create করার সময় পাঠিয়েছিলেন
];
$timestamp = time();
$body = json_encode($content);
$signText = $appId . $timestamp . $body;
$sign = hash_hmac('sha256', $signText, $appSecret);
$response = Http::withHeaders([
'Content-Type' => 'application/json;charset=utf-8',
'Appid' => $appId,
'Sign' => $sign,
'Timestamp' => $timestamp,
])->withBody($body, 'application/json')->post($url);
$result = $response->json();
if (($result['code'] ?? null) == 10000) {
// $result['data'] এ order status, deposit records ইত্যাদি থাকবে
return $result['data'];
}
Log::error('CCPayment getOrderInfo failed', $result);
return null;
}
// handle callback CCPAYMENT
public function handle(Request $request){
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$receivedAppId = $request->header('Appid');
$sign = $request->header('Sign');
$timestamp = $request->header('Timestamp');
$rawBody = $request->getContent();
// ধাপ ১: AppId ভেরিফাই করুন
if ($receivedAppId !== $appId) {
return response()->json(['msg' => 'Invalid AppId'], 401);
}
// ধাপ ২: Timestamp ভেরিফাই করুন (৫ মিনিটের বেশি পুরনো হলে reject)
$currentTimestamp = time();
if (abs($currentTimestamp - (int)$timestamp) > 300) {
return response()->json(['msg' => 'Timestamp expired'], 401);
}
// ধাপ ৩: Signature ভেরিফাই করুন
$signText = $appId . $timestamp;
if (strlen($rawBody) != 0) {
$signText .= $rawBody;
}
$expectedSign = hash_hmac('sha256', $signText, $appSecret);
if (!hash_equals($expectedSign, $sign)) {
return response()->json(['msg' => 'Invalid signature'], 402);
}
$data = json_decode($rawBody, true);
// ধাপ ৪: এটা কি activation request? আলাদাভাবে handle করুন
// if (isset($data['type']) && $data['type'] === 'ActivateWebhookURL') {
// return response()->json(['msg' => 'Success'], 200);
// }
// ধাপ ৫: এটা আসল transaction notification — এখানে business logic লিখুন
Log::info('CCPayment Webhook: Transaction notification', $data);
$notificationType = $data['type'] ?? null;
$msg = $data['msg'] ?? [];
$orderId = $msg['orderId'] ?? null;
$status = $msg['status'] ?? null;
if ($notificationType === 'ApiDeposit' && $orderId && $status === 'Success') {
Log::info('CCPayment Webhook: Transaction notification Success', [
'orderId' => $orderId,
]);
$invoiceData = invoice_unpaid_Model::where('Payer_ID', $orderId)->first();
if ($invoiceData) {
Log::info('CCPayment Webhook: Matched invoice', [
'INVOICE_ID' => $invoiceData->INVOICE_ID,
'orderId' => $orderId,
]);
$this->completeOrder_ccpayment($invoiceData->INVOICE_ID);
} else {
Log::warning('CCPayment Webhook: No matching invoice found', ['orderId' => $orderId]);
}
}
return response()->json(['code' => 10000, 'msg' => 'success']);
}
// getOrderInfo
public function getOrderInfo($orderId)
{
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$url = "https://ccpayment.com/ccpayment/v2/getAppOrderInfo"; // এন্ডপয়েন্ট নাম ডকুমেন্টেশনে ভেরিফাই করুন
$content = ["orderId" => $orderId];
$timestamp = time();
$body = json_encode($content);
$signText = $appId . $timestamp . $body;
$serverSign = hash_hmac('sha256', $signText, $appSecret);
$response = Http::withHeaders([
'Content-Type' => 'application/json;charset=utf-8',
'Appid' => $appId,
'Sign' => $serverSign,
'Timestamp' => $timestamp,
'User-Agent' => 'CCPayment-Client/1.0',
])->withBody($body, 'application/json')->post($url);
Log::info('Webhook Hit');
return response()->json($response->json());
}
// getCoinList
public function getCoinList()
{
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$url = "https://ccpayment.com/ccpayment/v2/getCoinList"; // এন্ডপয়েন্ট নাম ডকুমেন্টেশনে ভেরিফাই করুন
$timestamp = time();
$body = "";
$signText = $appId . $timestamp . $body;
$serverSign = hash_hmac('sha256', $signText, $appSecret);
$response = Http::withHeaders([
'Content-Type' => 'application/json;charset=utf-8',
'Appid' => $appId,
'Sign' => $serverSign,
'Timestamp' => $timestamp,
'User-Agent' => 'CCPayment-Client/1.0',
])->withBody($body, 'application/json')->post($url);
return response()->json($response->json());
}
// getFiatList
public function getFiatList()
{
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$url = "https://ccpayment.com/ccpayment/v2/getFiatList"; // এন্ডপয়েন্ট নাম ডকুমেন্টেশনে ভেরিফাই করুন
$timestamp = time();
$body = "";
$signText = $appId . $timestamp . $body;
$serverSign = hash_hmac('sha256', $signText, $appSecret);
$response = Http::withHeaders([
'Content-Type' => 'application/json;charset=utf-8',
'Appid' => $appId,
'Sign' => $serverSign,
'Timestamp' => $timestamp,
'User-Agent' => 'CCPayment-Client/1.0',
])->withBody($body, 'application/json')->post($url);
return response()->json($response->json());
}
// Create payment // checkoutUrl
public function PayWithCrypto_ccpayment(Request $Request, $InvoiceID, $Plan_ID)
{
$appId = env('CCPAYMENT_APP_ID');
$appSecret = env('CCPAYMENT_APP_SECRET');
$url = "https://ccpayment.com/ccpayment/v2/createAppOrderDepositAddress";
date_default_timezone_set('Asia/Dhaka'); # default_time
$date_now = date("Y/m/d H:i:s", strtotime("now")); # time now
$invoiceData = invoice_unpaid_Model::where('INVOICE_ID','=',$InvoiceID)->first();
if ($invoiceData){
$User_email = $invoiceData->INVOICE_User;
$merchant_order_id = $InvoiceID."_".$invoiceData->INVOICE_User;
$content = [
"orderId" => $merchant_order_id, // "test_order_" . time(),
"price" => $invoiceData->INVOICE_Price,
"coinId" => 1280,
"chain" => "BSC", // ✅ কনফার্মড — BEP20 প্রোটোকল
"fiatId" => 1033, // USDT working
"product" => $InvoiceID."_".$invoiceData->INVOICE_User."_".$invoiceData->Pay_Plan,
"returnUrl" => "https://10proxy.com/user/dashboard",
"closeUrl" => "https://10proxy.com/user/dashboard",
"generateCheckoutURL" => true,
"buyerEmail" => $User_email,
"expiredAt" => time() + 1800,
];
$timestamp = time();
$body = json_encode($content);
$signText = $appId . $timestamp . $body;
$serverSign = hash_hmac('sha256', $signText, $appSecret);
$response = Http::withHeaders([
'Content-Type' => 'application/json;charset=utf-8',
'Appid' => $appId,
'Sign' => $serverSign,
'Timestamp' => $timestamp,
'User-Agent' => 'CCPayment-Client/1.0',
])->withBody($body, 'application/json')->post($url);
invoice_unpaid_Model::where('INVOICE_ID', $InvoiceID)->update([ 'Payer_ID'=>$merchant_order_id, 'Payment_Type'=>"Crypto_ccpayment",'Payer_Details'=>$invoiceData->INVOICE_Price. " ".$InvoiceID, ]);
if ($response['msg'] == 'success'){
$payment_url = $response['data']['checkoutUrl'];
return redirect($payment_url);
}else{
return redirect('/Invoice');
}
// return response()->json($response->json());
}else{
return redirect('/Invoice');
// return 0;
}
}
// Complete order after payment: paid or overpaid → activate account
public function completeOrder_ccpayment($InvoiceID)
{
date_default_timezone_set('Asia/Dhaka');
$Pay_ccpayment_first_data = invoice_unpaid_Model::where('INVOICE_ID', $InvoiceID)
->where('Payment_Type', 'Crypto_ccpayment')
->first();
if (!$Pay_ccpayment_first_data) return false;
$merchant_order_id = $Pay_ccpayment_first_data->Payer_ID;
$User_Email = $Pay_ccpayment_first_data->INVOICE_User;
// v2 API দিয়ে order info + total paid বের করা
$orderInfo = $this->getOrderInfo_ccpayment($merchant_order_id);
if (!$orderInfo) return false;
$totalPaid = $this->getTotalPaidFromInfo($orderInfo);
$amountDue = floatval($orderInfo['amountToPay'] ?? 0);
if ($totalPaid <= 0 || $amountDue <= 0) return false;
// Paid বা Overpaid হলে অ্যাক্টিভেট করবো (আপনার আগের লজিকে ছিল 80% threshold, চাইলে রাখুন)
$isPaidOrOverpaid = $totalPaid >= $amountDue;
if (!$isPaidOrOverpaid) {
// Underpaid — শুধু status লগ করে রাখুন, একাউন্ট এক্টিভ করবেন না
invoice_unpaid_Model::where('INVOICE_ID', $InvoiceID)->update([
'Pay_Status' => 'Underpaid',
]);
return false;
}
$Plan_Data = plan_Model::where('Plan_ID', $Pay_ccpayment_first_data->Plan_ID)->first();
if (!$Plan_Data) return false;
$INVOICE_ID_now = $Plan_Data->INVOICE_ID;
$Plan_ID_now = $Plan_Data->Plan_ID;
$times = 1440 * $Plan_Data->Plan_Date;
$Proxy_Limit = $Plan_Data->Plan_Limit;
$Expiry_date_view = date("Y/m/d H:i:s", strtotime("+$times minutes"));
$status = $totalPaid > $amountDue ? 'Overpaid' : 'Successful';
$result = Invoice_Model::insert([
'Pay_Status' => 'COMPLETED',
'Payer_Details' => $merchant_order_id,
'INVOICE_ID' => $Pay_ccpayment_first_data->INVOICE_ID,
'INVOICE_Date' => $Pay_ccpayment_first_data->INVOICE_Date,
'INVOICE_User' => $User_Email,
'INVOICE_Price' => $Pay_ccpayment_first_data->INVOICE_Price,
'Licence_Expiry_Date' => $Expiry_date_view,
'Payment_Type' => 'Crypto',
'Pay_Plan' => $Pay_ccpayment_first_data->Pay_Plan,
'Pay_Price' => $Pay_ccpayment_first_data->Pay_Price,
'Pay_fee' => $Pay_ccpayment_first_data->Pay_fee,
'Pay_Days' => $Pay_ccpayment_first_data->Pay_Days,
]);
if ($result) {
authModel::where('User_Email', $User_Email)->update([
'Licence_Key_Status' => 'Active',
'Active_Licence_Key_Date' => $Expiry_date_view,
'Active_Proxy' => $Proxy_Limit,
'Use_Proxy' => 0,
]);
invoice_unpaid_Model::where('INVOICE_User', $User_Email)->delete();
use_proxy_Model::where('use_user', $User_Email)->delete();
my_rdp_Controller::my_rdp($User_Email, $INVOICE_ID_now, $Plan_ID_now);
}
return true;
}
// Helper: orderInfo array থেকে total paid বের করা (already-fetched data দিয়ে, extra API call ছাড়া)
private function getTotalPaidFromInfo($orderInfo)
{
$totalPaid = 0;
foreach ($orderInfo['paidList'] ?? [] as $record) {
if ($record['status'] === 'Success') {
$totalPaid += floatval($record['amount']);
}
}
return $totalPaid;
}
}
Post a Comment