<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
class GmoPaymentController extends Controller
{
public function index()
{
return view('gmo_payment');
}
// Bước 1: Tạo EntryTran để lấy AccessID và AccessPass
public function createEntryTran(Request $request)
{
$orderID = mt_rand(100000000, 999999999);
$token = $request->input('token');
$amount = 232;
$entryResponse = Http::asForm()->post(env('GMO_API_ENDPOINT') . '/EntryTran.idPass', [
'ShopID' => env('GMO_SHOP_ID'),
'ShopPass' => env('GMO_SHOP_PASSWORD'),
'OrderID' => $orderID,
'JobCd' => 'CAPTURE',
'Amount' => $amount,
'TdFlag' => '2', // Nếu có tức là có 3Ds không có thì thôi. 3ds phải có cái này là bắt buộc.
]);
\Log::info('EntryTran Response:', ['response' => $entryResponse->body()]);
parse_str($entryResponse->body(), $entryData);
if (isset($entryData['AccessID']) && isset($entryData['AccessPass'])) {
// Lưu dữ liệu giao dịch vào cache với key "gmo_order_{orderID}"
Cache:

ut('gmo_order_' . $orderID, [
'accessID' => $entryData['AccessID'],
'accessPass' => $entryData['AccessPass'],
'orderID' => $orderID,
'amount' => $amount
], now()->addMinutes(30));
// Lưu thêm mapping từ AccessID -> OrderID
Cache:

ut('gmo_access_' . $entryData['AccessID'], $orderID, now()->addMinutes(30));
return $this->executeTransaction($orderID, $entryData['AccessID'], $entryData['AccessPass'], $token, $amount);
} else {
return response()->json(['error' => 'Failed to create EntryTran'], 400);
}
}
public function executeTransaction($orderID, $accessID, $accessPass, $token, $amount)
{
$execParams = [
'ShopID' => env('GMO_SHOP_ID'),
'ShopPass' => env('GMO_SHOP_PASSWORD'),
'AccessID' => $accessID,
'AccessPass' => $accessPass,
'OrderID' => $orderID,
'Token' => $token,
'Method' => '1',//1: Bulk 2: Installment 3: Bonus (One time) 5: Revolving
'JobCd' => 'CAPTURE',
'RetUrl' => env('GMO_RETURN_URL'), // URL return sau khi xác thực nếu dùng 3Ds2 là bắt buộc
];
$execResponse = Http::asForm()
->post(env('GMO_API_ENDPOINT') . '/ExecTran.idPass', $execParams);
// \Log::info('Executing transaction with Tds2RetUrl:', ['Tds2RetUrl' => $execParams['Tds2RetUrl']]);
\Log::info('ExecTran Response:', ['response' => $execResponse->body()]);
parse_str($execResponse->body(), $execData);
if (isset($execData['ErrCode'])) {
\Log::error('ExecTran Error:', ['data' => $execData]);
return response()->json([
'error' => 'ExecTran Error',
'code' => $execData['ErrCode'],
'info' => $execData['ErrInfo'] ?? 'Unknown error',
'status' => 'error',
], 400);
}
if (isset($execData['ACS']) && $execData['ACS'] == '2') {
\Log::info('Redirecting to 3D Secure:', ['url' => $execData['RedirectUrl']]);
$t = $execData['t'] ?? null;
$redirectUrl = $execData['RedirectUrl'] ?? null;
$url = $redirectUrl.'&t='.$t;
\Log::info('NEW URL PAYMENT'. $url);
return response()->json(['status' => 'ok', 'redirectUrl' => $url]);
}
return response()->json([
'error' => 'This card does not support 3D Secure. Please use a card with 3D Secure enabled.',
'status' => 'error'
], 400);
}
public function handleCallback(Request $request)
{
\Log::info('Received callback:', $request->all());
// Lấy AccessID từ request (giả sử key là "AccessID")
$data = $request->all();
$accessID = $data['AccessID'] ?? null;
if (!$accessID) {
\Log::error('Missing AccessID in callback', $request->all());
return response()->json([
'error' => 'Missing AccessID',
'status' => 'error'
], 400);
}
// Lấy OrderID từ mapping cache với key "gmo_access_{AccessID}"
$orderID = Cache::get('gmo_access_' . $accessID);
if (!$orderID) {
\Log::error('Mapping for AccessID not found in cache', ['AccessID' => $accessID]);
return response()->json([
'error' => 'Transaction expired or invalid cache data',
'status' => 'error'
], 400);
}
// Lấy dữ liệu giao dịch từ cache theo key "gmo_order_{orderID}"
$orderData = Cache::get('gmo_order_' . $orderID);
if (!$orderData) {
\Log::error('Cache data missing for transaction', ['orderID' => $orderID]);
return response()->json([
'error' => 'Transaction expired or invalid cache data',
'status' => 'error'
], 400);
}
$accessPass = $orderData['accessPass'];
$amount = $orderData['amount'];
\Log::info('Processing transaction completion', [
'AccessID' => $accessID,
'AccessPass' => $accessPass,
'OrderID' => $orderID,
'amount' => $amount
]);
$afterTranParams = [
'AccessID' => $accessID,
'AccessPass' => $accessPass,
];
$afterTranResponse = Http::asForm()
->post(env('GMO_API_ENDPOINT') . '/SecureTran2.idPass', $afterTranParams);
\Log::info('SecureTran2 Response:', ['response' => $afterTranResponse->body()]);
parse_str($afterTranResponse->body(), $alterTranData);
if (isset($alterTranData['ErrCode'])) {
\Log::error('SecureTran2 Error:', ['data' => $alterTranData]);
return response()->json([
'error' => 'SecureTran2 Error',
'code' => $alterTranData['ErrCode'],
'info' => $alterTranData['ErrInfo'] ?? 'Unknown error',
'status' => 'error'
], 400);
}
\Log::info('data', ['response' => $afterTranResponse->body()]);
// Xóa dữ liệu cache sau khi giao dịch hoàn tất
Cache::forget('gmo_order_' . $orderID);
Cache::forget('gmo_access_' . $accessID);
return response()->json(['data' => $afterTranResponse-> body()]);
}
}