braintree = $braintree; $this->braintree->init(); } public function authorizeView(array $data) { $data['gateway'] = $this->braintree; $data['client_token'] = $this->braintree->gateway->clientToken()->generate(); return render('gateways.braintree.ach.authorize', $data); } public function authorizeResponse(Request $request) { $request->validate([ 'nonce' => ['required'], 'gateway_type_id' => ['required'], ]); $customer = $this->braintree->findOrCreateCustomer(); $result = $this->braintree->gateway->paymentMethod()->create([ 'customerId' => $customer->id, 'paymentMethodNonce' => $request->nonce, 'options' => [ 'usBankAccountVerificationMethod' => \Braintree\Result\UsBankAccountVerification::NETWORK_CHECK, ], ]); if ($result->success && optional($result->paymentMethod)->verified) { $account = $result->paymentMethod; try { $payment_meta = new \stdClass; $payment_meta->brand = (string)$account->bankName; $payment_meta->last4 = (string)$account->last4; $payment_meta->type = GatewayType::BANK_TRANSFER; $payment_meta->state = 'authorized'; $data = [ 'payment_meta' => $payment_meta, 'token' => $account->token, 'payment_method_id' => $request->gateway_type_id, ]; $this->braintree->storeGatewayToken($data, ['gateway_customer_reference' => $customer->id]); return redirect()->route('client.payment_methods.index')->withMessage(ctrans('texts.payment_method_added')); } catch (\Exception $e) { return $this->braintree->processInternallyFailedPayment($this->braintree, $e); } } return back()->withMessage(ctrans('texts.unable_to_verify_payment_method')); } public function paymentView(array $data) { $data['gateway'] = $this->braintree; $data['currency'] = $this->braintree->client->getCurrencyCode(); $data['payment_method_id'] = GatewayType::BANK_TRANSFER; $data['amount'] = $this->braintree->payment_hash->data->amount_with_fee; return render('gateways.braintree.ach.pay', $data); } public function paymentResponse(PaymentResponseRequest $request) { $request->validate([ 'source' => ['required'], 'payment_hash' => ['required'], ]); $customer = $this->braintree->findOrCreateCustomer(); $token = ClientGatewayToken::query() ->where('client_id', auth()->guard('contact')->user()->client->id) ->where('id', $this->decodePrimaryKey($request->source)) ->firstOrFail(); $result = $this->braintree->gateway->transaction()->sale([ 'amount' => $this->braintree->payment_hash->data->amount_with_fee, 'paymentMethodToken' => $token->token, 'options' => [ 'submitForSettlement' => true ], ]); if ($result->success) { $this->braintree->logSuccessfulGatewayResponse(['response' => $request->server_response, 'data' => $this->braintree->payment_hash], SystemLog::TYPE_BRAINTREE); return $this->processSuccessfulPayment($result); } return $this->processUnsuccessfulPayment($result); } private function processSuccessfulPayment($response) { $state = $this->braintree->payment_hash->data; $data = [ 'payment_type' => PaymentType::ACH, 'amount' => $this->braintree->payment_hash->data->amount_with_fee, 'transaction_reference' => $response->transaction->id, 'gateway_type_id' => GatewayType::BANK_TRANSFER, ]; $payment = $this->braintree->createPayment($data, Payment::STATUS_COMPLETED); SystemLogger::dispatch( ['response' => $response, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_BRAINTREE, $this->braintree->client, $this->braintree->client->company, ); return redirect()->route('client.payments.show', ['payment' => $this->braintree->encodePrimaryKey($payment->id)]); } private function processUnsuccessfulPayment($response) { $this->braintree->sendFailureMail($response->transaction->additionalProcessorResponse); $message = [ 'server_response' => $response, 'data' => $this->braintree->payment_hash->data, ]; SystemLogger::dispatch( $message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_BRAINTREE, $this->braintree->client, $this->braintree->client->company, ); throw new PaymentFailed($response->transaction->additionalProcessorResponse, $response->transaction->processorResponseCode); } }