public function proceedPaymentHNB(Request $request)
{
$order_id = $request->input("order_id");
$order = Order::where("id", $order_id)->first();
if ($order_id != null && $order != null) {
$transaction_ref = $this->addTransactionEntry($order_id);
if ($transaction_ref != null) {
// Transaction created
$this->reference_number = $transaction_ref;
$this->amount = $order->total_amount;
$this->bill_to_address_line1 = $order->delivery_address;
$this->bill_to_address_city = $order->delivery_city;
$this->bill_to_address_country = $order->delivery_country_code;
$this->bill_to_address_postal_code = $order->delivery_delivery_zip_code;
$this->bill_to_forename = $order->user->user_first_name;
$this->bill_to_surname = $order->user->user_last_name;
$this->bill_to_email = $order->user->user_email;
$this->bill_to_phone = $order->user->user_mobile;
$this->signed_date_time = Carbon::now()->toIso8601ZuluString(); //Carbon::now()->format("Y-m-dTh:i:sZ");
$this->transaction_uuid = APIHelper::generateRandomString(30);
$request_form_data = [
"access_key" => $this->access_key,
"profile_id" => $this->profile_id,
"transaction_type" => $this->transaction_type,
"reference_number" => $this->reference_number,
"amount" => $this->amount,
"locale" => $this->locale,
"transaction_uuid" => $this->transaction_uuid,
"signed_date_time" => $this->signed_date_time,
"signed_field_names" => $this->signed_field_names,
"unsigned_field_names" => "",
"currency" => $this->currency,
"payment_method" => $this->payment_method,
"bill_to_forename" => $this->bill_to_forename,
"bill_to_surname" => $this->bill_to_surname,
"bill_to_email" => $this->bill_to_email,
"bill_to_phone" => $this->bill_to_phone,
"bill_to_address_line1" => $this->bill_to_address_line1,
"bill_to_address_city" => $this->bill_to_address_city,
"bill_to_address_country" => $this->bill_to_address_country,
"bill_to_address_postal_code" => $this->bill_to_address_postal_code,
];
$this->signature = $this->makeSignature($request_form_data);
$request_form_data["signature"] = $this->signature;
$log_data = ["ACTION" => "PAYMENT REQUEST", "FULL_REQUEST" => $request_form_data];
$this->apiLog($log_data);
echo '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ShayInt Payment</title>
</head>
<body>
<h1 align="center">Processing your Transaction</h1>
<form method="post" action="' . $this->pay_url . '" name="checkout_form" style="display:none;">
<div align="center">
<input id="access_key" type="hidden" value="' . $this->access_key . '" name="access_key">
<input id="profile_id" type="hidden" value="' . $this->profile_id . '" name="profile_id">
<input id="transaction_type" type="hidden" value="' . $this->transaction_type . '" name="transaction_type">
<input id="reference_number" type="hidden" value="' . $this->reference_number . '" name="reference_number">
<input id="amount" type="hidden" value="' . $this->amount . '" name="amount" >
<input id="locale" type="hidden" value="' . $this->locale . '" name="locale" >
<input id="transaction_uuid" type="hidden" value="' . $this->transaction_uuid . '" name="transaction_uuid">
<input id="signed_date_time" type="hidden" value="' . $this->signed_date_time . '" name="signed_date_time" >
<input id="signed_field_names" type="hidden" value="' . $this->signed_field_names . '" name="signed_field_names" >
<input id="unsigned_field_names" type="hidden" value="' . $this->unsigned_field_names . '" name="unsigned_field_names" >
<input id="currency" type="hidden" value="' . $this->currency . '" name="currency" >
<input id="signature" type="hidden" value="' . $this->signature . '" name="signature">
<input id="payment_method" type="hidden" value="' . $this->payment_method . '" name="payment_method">
<input id="bill_to_forename" type="hidden" value="' . $this->bill_to_forename . '" name="bill_to_forename">
<input id="bill_to_surname" type="hidden" value="' . $this->bill_to_surname . '" name="bill_to_surname">
<input id="bill_to_email" type="hidden" value="' . $this->bill_to_email . '" name="bill_to_email">
<input id="bill_to_phone" type="hidden" value="' . $this->bill_to_phone . '" name="bill_to_phone">
<input id="bill_to_address_city" type="hidden" value="' . $this->bill_to_address_city . '" name="bill_to_address_city">
<input id="bill_to_address_line1" type="hidden" value="' . $this->bill_to_address_line1 . '" name="bill_to_address_line1">
<input id="bill_to_address_country" type="hidden" value="' . $this->bill_to_address_country . '" name="bill_to_address_country">
<input id="bill_to_address_postal_code" type="hidden" value="' . $this->bill_to_address_postal_code . '" name="bill_to_address_postal_code">
<h3 align="center"> Please click on the Submit button to continue processing.<br>
<input type="submit" value="Submit">
</div>
</form>
<script>document.forms["checkout_form"].submit();</script>
</body>
</html>
';
} else {
// Transaction not created
Log::critical("Transaction not created for oder_id=" . $order_id);
return redirect()->to(web_base_path('show-payment-response?result=error'));
}
} else {
// Invalid order id
Log::critical("Invalid order id - oder_id=" . $order_id);
return redirect()->to(web_base_path('show-payment-response?result=error'));
}
}
public function getPaymentGatewayResponseHNB(Request $request)
{
$ResponseCode = $request->input('decision');
$ReasonCode = $request->input('reason_code');
$ReasonCodeDesc = $request->input('message');
$signature = $request->input('signature');
$OrderID = $request->input('req_reference_number');
$transaction = Transaction::where("transaction_reference", $OrderID)->first();
$log_data = ["ACTION" => "PAYMENT RESPONSE", "DECISION" => $request->input('decision'), "ReasonCode" => $request->input('reason_code'), "ReasonCodeDesc" => $request->input('message'), "FULL_RESPONSE" => $request->input()];
$this->apiLog($log_data);
if (isset($ResponseCode)) {
if ($ResponseCode == "ACCEPT") {
if ($ReasonCode == 100) {
// Transaction Approved.
if ($transaction != null) {
$db_signature = $this->makeSignature($request);
$transaction->pg_response_code = $ResponseCode;
$transaction->pg_response_desc = $ReasonCodeDesc;
$transaction->pg_full_response = json_encode($request->input());
$transaction->save();
// Check signatures
if ($db_signature == $request->signature) {
// Success transaction and Signature matched
$transaction->order->success_transaction_id = $transaction->id;
$transaction->order->payment_status = 1;
$transaction->order->save();
$transaction->order->cart->status = 1;
$transaction->order->cart->completed_at = now()->toDateTimeString();
$transaction->order->cart->save();
//Reduce Stock
$reduceStock = new ProductController();
$reduceStock->reduceStock($transaction->order->cart->id);
//Change Status of Giftcard as 'purchased'
$cart_giftcards = CartGiftCard::where(['cart_id' => $transaction->order->cart->id])->get();
foreach ($cart_giftcards as $cart_giftcard) {
GiftCardController::purchaseGiftCard($cart_giftcard->gift_card_id);
}
// Order confirmation email to customer
Mail::to($transaction->order->user->user_email)->send(new CustomerOrderConfirmation($transaction->order));
// Order confirmation email to backend
Mail::to(config('shayInt.BACKEND_MAIL_ADDRESS'))->send(new BackendOrderConfirmation($transaction->order));
return redirect()->to(web_base_path('show-payment-response?result=success&message=' . $ReasonCodeDesc));
} else {
// Success transaction but Signature not match (BOGUS TRANSACTION)
Log::critical("Success transaction but Signature not match (BOGUS TRANSACTION) - Signatures=> " . $db_signature . "!=" . $signature . " Response=>" . json_encode($request->input()));
$transaction->order->success_transaction_id = $transaction->id;
$transaction->order->payment_status = 3;
$transaction->order->save();
$transaction->order->cart->status = 3;
$transaction->order->cart->completed_at = now()->toDateTimeString();
$transaction->order->cart->save();
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
}
} else {
// Response OrderID not use as transaction_reference in transaction data.
Log::critical("Response OrderID not use as transaction_reference in transaction data.");
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
}
}
} elseif ($ResponseCode == "CANCEL") {
// Transaction Declined.
Log::critical("Transaction Cancelled");
if ($transaction != null) {
$transaction->pg_response_code = $ResponseCode;
$transaction->pg_response_desc = $ReasonCodeDesc;
$transaction->pg_full_response = json_encode($request->input());
$transaction->save();
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
} else {
// Response OrderID not use as transaction_reference in transaction data.
Log::critical("Response OrderID not use as transaction_reference in transaction data.");
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
}
}elseif($ResponseCode == "DECLINE") {
// Transaction Decline.
Log::critical("Transaction Declined");
if ($transaction != null) {
$transaction->pg_response_code = $ResponseCode;
$transaction->pg_response_desc = $ReasonCodeDesc;
$transaction->pg_full_response = json_encode($request->input());
$transaction->save();
if($ReasonCode == 234||$ReasonCode == 236||$ReasonCode == 481){
return redirect()->to(web_base_path('show-payment-response?result=error&message='));
}
else{
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
}
} else {
// Response OrderID not use as transaction_reference in transaction data.
Log::critical("Response OrderID not use as transaction_reference in transaction data.");
return redirect()->to(web_base_path('show-payment-response?result=error&message='));
}
}else {
// Transaction Error.
Log::critical("Transaction Error");
if ($transaction != null) {
$transaction->pg_response_code = $ResponseCode;
$transaction->pg_response_desc = $ReasonCodeDesc;
$transaction->pg_full_response = json_encode($request->input());
$transaction->save();
return redirect()->to(web_base_path('show-payment-response?result=error&message='));
} else {
// Response OrderID not use as transaction_reference in transaction data.
Log::critical("Response OrderID not use as transaction_reference in transaction data.");
return redirect()->to(web_base_path('show-payment-response?result=error&message='));
}
}
} else {
// Invalid response from CyberSource
Log::critical("Invalid response from CyberSource");
return redirect()->to(web_base_path('show-payment-response?result=error&message=' . $ReasonCodeDesc));
}
}
private function addTransactionEntry($order_id, $currency_code = "USD")
{
try {
$order = Order::where('id', $order_id)->first();
$client_ip = request()->ip();
if ($order != null) {
// order exists
$transaction_ref = (string) round(microtime(true) * 1000) . rand(100, 999);
$transaction = new Transaction();
$transaction->order_id = $order_id;
$transaction->user_id = $order->user_id;
$transaction->currency_code = $currency_code;
$transaction->amount = $order->total_amount;
$transaction->transaction_reference = $transaction_ref;
$transaction->pg_response_code = null;
$transaction->pg_response_desc = null;
$transaction->pg_full_response = null;
$transaction->client_ip = $client_ip;
} else {
// order not exists
$log_text = ["ACTION" => "PAYMENT GATEWAY INVALID ORDER ID", "CLIENT_IP" => $client_ip, "ORDER_ID" => $order_id];
apiSecurityLog($log_text);
return null;
}
if ($transaction->save()) {
return $transaction_ref;
} else {
return null;
}
} catch (\Exception $e) {
Log::critical("PaymentGatewayController addTransactionEntry ERROR - Client IP = " . $client_ip);
Log::critical($e);
return null;
}
}
private function makeSignature($request_form_data)
{
return $this->signData($this->buildDataToSign($request_form_data), $this->secret_key);
}
private function signData($data, $secret_key)
{
return base64_encode(hash_hmac('sha256', $data, $secret_key, true));
}
private function buildDataToSign($request_form_data)
{
$signedFieldNames = explode(",", $request_form_data["signed_field_names"]);
foreach ($signedFieldNames as $field) {
$dataToSign[] = $field . "=" . $request_form_data[$field];
}
return $this->commaSeparate($dataToSign);
}
private function commaSeparate($dataToSign)
{
return implode(",", $dataToSign);
}
private static function apiLog($log_text)
{
$log_file_path = storage_path('logs/payment_gateway/payment.log');
$log = [$log_text];
$orderLog = new Logger("HNB");
$orderLog->pushHandler(new StreamHandler($log_file_path), Logger::INFO);
$orderLog->info('Log', $log);
}
}