public function do_checkout(Request $request) { $fields = ['email' => 'required|email', 'phone' => 'required|digits:10', 'cc_num' => 'required|numeric', 'cc_exp' => 'required|date_format:m/Y', 'cc_cvv' => 'required|numeric']; foreach ($this->fields as $k => $info) { $k = "billing_{$k}"; $fields[$k] = $info['validation']; } foreach ($this->fields as $k => $info) { $k = "shipping_{$k}"; $v = $info['validation']; $v = preg_replace("/required/", "required_without:same_as_billing", $v); $fields[$k] = $v; } $this->validate($request, $fields); $data = $request->input(); if ($request->input('same_as_billing')) { foreach ($this->fields as $field_name => $field_info) { $data["shipping_{$field_name}"] = $data["billing_{$field_name}"]; } } $gateway_server = 'SagePay\\Direct'; $transaction_id = 'muscle-' . uniqid() . '-' . microtime(true); session('transaction_id', $transaction_id); list($cc_exp_y, $cc_exp_m) = explode('/', $data['cc_exp']); // Define the card details. // The card and customer are mixed into one object for now. $card = new CreditCard(['firstName' => $data['shipping_first_name'], 'lastName' => $data['shipping_last_name'], 'number' => $data['cc_num'], 'expiryMonth' => $cc_exp_m, 'expiryYear' => $cc_exp_y, 'CVV' => $data['cc_cvv'], 'billingAddress1' => $data['billing_address_1'], 'billingAddress2' => $data['billing_address_2'], 'billingState' => $data['billing_state'], 'billingCity' => $data['billing_city'], 'billingPostcode' => $data['billing_zip'], 'billingCountry' => $data['billing_country'], 'shippingAddress1' => $data['shipping_address_1'], 'shippingAddress2' => $data['shipping_address_2'], 'shippingState' => $data['shipping_state'], 'shippingCity' => $data['shipping_city'], 'shippingPostcode' => $data['shipping_zip'], 'shippingCountry' => $data['shipping_country']]); $gateway = OmniPay::create($gateway_server)->setVendor(env('SAGEPAY_MERCHANT_NAME'))->setTestMode(true); $requestMessage = $gateway->purchase(['amount' => $this->cart->total(), 'currency' => 'GBP', 'card' => $card, 'transactionId' => $transaction_id, 'description' => "Retail order"]); $responseMessage = $requestMessage->send(); if ($responseMessage->isSuccessful()) { /* SAVE TRANSACTION TO ORDERS TABLE $order = Order::create([ 'status' => method_exists($responseMessage, 'getStatus') ? $responseMessage->getStatus() : $responseMessage->getCode(), 'transactionReference' => $responseMessage->getTransactionReference(), ]) */ session('order_id', $order->id); \Mail::send(['text' => 'emails.order'], ['transaction_id' => $transaction_id, 'order' => $this->order], function ($m) use($data) { $m->from(env('ADMIN_EMAIL'), env('ADMIN_NAME'))->bcc(env('ADMIN_EMAIL'), env('ADMIN_NAME'))->to($data['email'])->subject('OnlyMsucle Order Confirmation'); }); return redirect(route('checkout.thanks')); } return redirect(route('checkout'))->withInput()->with(['reason' => $responseMessage->getStatus()]); }
// If we can't find the transaction, or it is in the wrong status, // then bail out now. // FIXED: I think instead of bailing out like this, we could return // a proper response. We do this by setting an empty // transactionReference before doing the send(); that will // catch the post as invalid. if (empty($transaction) || $transaction['finalStatus'] != 'PENDING') { // vendorTxCode missing or invalid - aborting $transactionReference = null; } else { $transactionReference = $transaction['transactionReference']; } // Get the gateway driver. // Don't forget to use your own vendor name. // Always "Server". "Direct" will never get here. $gateway = OmniPay::create('SagePay\\Server')->setVendor(getenv('VENDOR'))->setTestMode(true); // Get the "complete purchase" message. $requestMessage = $gateway->completePurchase(['transactionReference' => $transactionReference]); // Do a "send" - this will validate everything. try { $responseMessage = $requestMessage->send(); } catch (\Exception $e) { // InvalidResponseException will not catch a null transactionReference. // You may want to catch them separately and return different error messages. // This is a nasty hack, manually creating a message in the // event of an exception caused by a security failure. $requestMessage = $gateway->completePurchase([]); $responseMessage = new ServerCompleteAuthorizeResponse($requestMessage, []); $responseMessage->invalid($finalUrl, $e->getMessage()); } // Handle the actions based on successful (or not) authorisation
$transactionId = 'phpne-demo-' . rand(10000000, 99999999); // Store the transaction ID in the session. // We will need it after returning from the gateway. $_SESSION['transactionId'] = $transactionId; // Define the card details. // The card and customer are mixed into one object for now. $card = new CreditCard(['firstName' => 'Jason', 'lastName' => 'Judge', 'number' => '4929000000006', 'expiryMonth' => '12', 'expiryYear' => '2016', 'CVV' => '123', 'billingAddress1' => 'Campus North', 'billingAddress2' => '5 Carliol Square', 'billingState' => null, 'billingCity' => 'Newcastle Upon Tyne', 'billingPostcode' => 'NE1', 'billingCountry' => 'GB', 'shippingAddress1' => 'Campus North', 'shippingAddress2' => '5 Carliol Square', 'billingState' => null, 'shippingCity' => 'Newcastle Upon Tyne', 'shippingPostcode' => 'NE1', 'shippingCountry' => 'GB']); // Create the gateway. // You will need your own test vendor name and also will // need to give SagePay your server's IP address. // We will run the API in test mode, which automatically // switches to the test endpoint URLs. if ($gateway_server == 'SagePay\\Direct' || $gateway_server == 'SagePay\\Server') { $gateway = OmniPay::create($gateway_server)->setVendor(getenv('VENDOR'))->setTestMode(true)->setReferrerId('3F7A4119-8671-464F-A091-9E59EB47B80C'); } elseif ($gateway_server == 'AuthorizeNet_SIM' || $gateway_server == 'AuthorizeNet_DPM') { $gateway = OmniPay::create($gateway_server)->setApiLoginId(getenv('API_LOGIN_ID'))->setTransactionKey(getenv('TRANSACTION_KEY'))->setHashSecret(getenv('HASH_SECRET'))->setTestMode(true)->setDeveloperMode(true); } // Get the message for the service we want - purchase in this case. $requestMessage = $gateway->purchase(['amount' => '99.99', 'currency' => 'GBP', 'card' => $card, 'transactionId' => $transactionId, 'description' => 'Pizzas for everyone', 'returnUrl' => URL::directory() . '/sagepay-confirm.php', 'notifyUrl' => URL::directory() . '/authorizenet-confirm.php']); // Process the service request. // It may involve sending it to the gateway, and it may not. $responseMessage = $requestMessage->send(); // Store the result. // Note here that SagePay has getStatus() while Authorize.Net has getCode(). These all need // to be nornalised. $transaction = Storage::update($transactionId, ['finalStatus' => 'PENDING', 'status' => method_exists($responseMessage, 'getStatus') ? $responseMessage->getStatus() : $responseMessage->getCode(), 'message' => 'Awaiting notify', 'transactionReference' => $responseMessage->getTransactionReference()]); if ($responseMessage->isSuccessful()) { echo "<h2 class='alert alert-success'><span class='glyphicon glyphicon-ok-sign'></span><strong>All finished and all successful.</strong></h2>"; $transaction = Storage::update($transactionId, ['finalStatus' => 'APPROVED']); echo "<p>The final stored transaction:</p>"; dump($transaction);