Merhabalar uzun zaman olmuştu soru sormayalı 😃
Sorumu güncelliyorum şuanda.
{
"success": false,
"message": "Guvenlik Kodu hatali",
"order_id": "677f7bfd9efad",
"error_code": "99",
"details": {
"mdstatus": "7",
"response": "Error",
"procReturnCode": "99",
"errorMessage": "Guvenlik Kodu hatali"
}
}
Bu hatayı alıyorum.
Kart bilgileri vb her şey doğru ama bu hatayı neden alıyorum bulamadım.
https://dev.garantibbva.com.tr/api-katalog
<?php
namespace App\Services;
class GarantiPaymentService
{
private function generateHashPassword()
{
$password = "123qweASD"; // Terminal provision password
// $terminalId = str_pad("30691297", 9, "0", STR_PAD_LEFT); // 9 haneli terminal ID
$terminalId="30691297";
$data = [
$password,
str_pad((int)$terminalId, 9, 0, STR_PAD_LEFT)
];
$shaData = sha1(implode('', $data));
return strtoupper($shaData);
}
private function generate3DHash($orderId, $amount)
{
$terminalId = "30691297";
$successUrl = "http://127.0.0.1:8000/api/payment/success";
$errorUrl = "http://127.0.0.1:8000/api/payment/error";
$storeKey = "12345678";
$currencyCode = "949".
// 1. Adım: Terminal Şifresi Hash'i
$hashedPassword = $this->generateHashPassword();
// 2. Adım: Hash String
$hashStr = $terminalId .
$orderId .
$amount .
$currencyCode.
$successUrl .
$errorUrl .
$type="".
"sales" . // type
"0" . // installment
$storeKey .
$hashedPassword;
// 3. Adım: Final Hash
return strtoupper(hash('sha512', $hashStr));
}
public function prepareThreeDPayment($validated)
{
$orderId = uniqid();
$amount = number_format($validated['amount'] * 100, 0, '', '');
// Hash hesapla
$secure3dhash = $this->generate3DHash($orderId, $amount);
// Form verilerini hazırla
$formData = [
'mode' => 'TEST',
'secure3dsecuritylevel' => '3D_PAY',
'apiversion' => '512',
'terminalprovuserid' => 'PROVAUT',
'terminaluserid' => 'PROVAUT',
'terminalid' => '30691297',
'terminalmerchantid' => '7000679',
'orderid' => $orderId,
'successurl' => 'http://127.0.0.1:8000/api/payment/success',
'errorurl' => 'http://127.0.0.1:8000/api/payment/error',
'customeremailaddress' => $validated['customer_email'],
'customeripaddress' => $validated['customer_ip'],
'txntype' => 'sales',
'txnamount' => $amount,
'txncurrencycode' => '949',
'txninstallmentcount' => '0',
'secure3dhash' => $secure3dhash,
'cardnumber' => $validated['card_number'],
'cardexpiredatemonth' => $validated['expire_month'],
'cardexpiredateyear' => $validated['expire_year'],
'cardcvv2' => $validated['cvv'],
'cardholdername' => $validated['card_holder'],
'lang' => 'tr',
'txntimestamp' => gmdate("Y-m-d\TH:i:s\Z"),
'refreshtime' => '0',
'companyname' => 'TEST FIRMA'
];
// Debug için hash hesaplama detaylarını logla
\Log::info('3D Hash Details', [
'terminalId' => '30691297',
'orderId' => $orderId,
'amount' => $amount,
'successUrl' => 'http://127.0.0.1:8000/api/payment/success',
'errorUrl' => 'http://127.0.0.1:8000/api/payment/error',
'type' => 'sales',
'installment' => '0',
'storeKey' => '12345678',
'securityData' => $this->generateHashPassword(),
'finalHash' => $secure3dhash
]);
// Form oluştur
$form = '<form id="garanti3d_form" method="post" action="https://sanalposprovtest.garantibbva.com.tr/servlet/gt3dengine">';
foreach ($formData as $key => $value) {
$form .= sprintf('<input type="hidden" name="%s" value="%s">',
htmlspecialchars($key),
htmlspecialchars($value, ENT_QUOTES)
);
}
$form .= '<input type="submit" value="Ödeme Yap" style="display:none;">';
$form .= '</form>';
$form .= '<script>document.getElementById("garanti3d_form").submit();</script>';
return $form;
}
}
Controller
<?php
namespace App\Http\Controllers\Payments;
use App\Http\Controllers\Controller;
use App\Services\GarantiPaymentService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class PaymentController extends Controller
{
protected $garantiService;
public function __construct(GarantiPaymentService $garantiService)
{
$this->garantiService = $garantiService;
}
/**
* 3D Ödeme başlat
*/
public function initiate3DPayment(Request $request)
{
try {
$validator = Validator::make($request->all(), [
'amount' => 'required|numeric|min:1',
'customer_email' => 'required|email',
'customer_ip' => 'required|ip',
'card_number' => 'required|string|min:15|max:16',
'card_holder' => 'required|string|max:50',
'expire_month' => 'required|string|size:2',
'expire_year' => 'required|string|size:2',
'cvv' => 'required|string|min:3|max:4',
'installment' => 'sometimes|integer|min:0|max:12'
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors()
], 422);
}
$formHtml = $this->garantiService->prepareThreeDPayment($validator->validated());
return response($formHtml)->header('Content-Type', 'text/html');
} catch (\Exception $e) {
\Log::error('3D Payment Error:', [
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return response()->json([
'success' => false,
'message' => 'Ödeme başlatılırken bir hata oluştu: ' . $e->getMessage()
], 500);
}
}
/**
* Başarılı ödeme callback
*/
public function successCallback(Request $request)
{
Log::info('3D Success Callback Parameters:', $request->all());
$mdStatus = $request->get('mdstatus');
$response = $request->get('response');
$procReturnCode = $request->get('procreturncode');
$orderId = $request->get('orderid', $request->get('oid'));
$threeDHash = $request->get('secure3dhash');
// 3D Doğrulama ve Hata Kodları Kontrolü
if ($mdStatus == "7" || $procReturnCode == "99") {
Log::error('3D Auth Failed:', [
'mdstatus' => $mdStatus,
'mderrormessage' => $request->get('mderrormessage'),
'procReturnCode' => $procReturnCode,
'errorMessage' => $request->get('errmsg')
]);
// 3D Hash hatasının detaylarını logla
$calculatedHash = $this->garantiService->recalculateHash($request->all());
Log::info('Hash Comparison:', [
'received' => $threeDHash,
'calculated' => $calculatedHash,
'match' => $threeDHash === $calculatedHash
]);
return response()->json([
'success' => false,
'message' => $request->get('mderrormessage', 'Güvenlik doğrulaması başarısız'),
'order_id' => $orderId,
'error_code' => $procReturnCode,
'details' => [
'mdstatus' => $mdStatus,
'procReturnCode' => $procReturnCode,
'errorMessage' => $request->get('errmsg')
]
], 400);
}
// Başarılı işlem
if ($response == "Approved") {
return response()->json([
'success' => true,
'message' => 'Ödeme başarıyla tamamlandı',
'order_id' => $orderId,
'transaction_id' => $request->get('transid'),
'auth_code' => $request->get('authcode'),
'ref_no' => $request->get('retrefnum'),
'amount' => number_format($request->get('txnamount') / 100, 2),
'installment' => $request->get('txninstallmentcount')
]);
}
// Diğer hatalar
return response()->json([
'success' => false,
'message' => $request->get('errmsg', 'Ödeme işlemi başarısız'),
'order_id' => $orderId,
'error_code' => $procReturnCode
], 400);
}
public function errorCallback(Request $request)
{
Log::error('3D Error Callback Parameters:', $request->all());
return response()->json([
'success' => false,
'message' => $request->get('mderrormessage', 'Ödeme işlemi başarısız'),
'order_id' => $request->get('orderid', $request->get('oid')),
'error_code' => $request->get('procreturncode'),
'details' => [
'mdstatus' => $request->get('mdstatus'),
'response' => $request->get('response'),
'procReturnCode' => $request->get('procreturncode'),
'errorMessage' => $request->get('errmsg')
]
], 400);
}
/**
* Test sayfası
*/
public function testPage()
{
return view('payment.test-form');
}
}