WePay authorize for Bank Transfer

This commit is contained in:
David Bomba 2021-06-16 16:41:29 +10:00
parent d4f27bb3ee
commit 43ff685543
6 changed files with 402 additions and 4 deletions

View File

@ -41,4 +41,35 @@ class InvoicePresenter extends EntityPresenter
return '';
}
}
public function rBits()
{
$properties = new \stdClass();
$properties->terms_text = $this->terms;
$properties->note = $this->public_notes;
$properties->itemized_receipt = [];
foreach ($this->line_items as $item) {
$properties->itemized_receipt[] = $this->itemRbits($item);
}
$data = new stdClass();
$data->receive_time = time();
$data->type = 'transaction_details';
$data->source = 'user';
$data->properties = $properties;
return [$data];
}
public function itemRbits($item)
{
$data = new stdClass();
$data->description = $item->notes;
$data->item_price = floatval($item->cost);
$data->quantity = floatval($item->quantity);
$data->amount = round($data->item_price * $data->quantity, 2);
return $data;
}
}

View File

@ -12,20 +12,245 @@
namespace App\PaymentDrivers\WePay;
use App\Exceptions\PaymentFailed;
use Illuminate\Http\Request;
use App\Models\ClientGatewayToken;
use App\Models\GatewayType;
use App\PaymentDrivers\WePayPaymentDriver;
class ACH
{
public $wepay;
public $wepay_payment_driver;
public function __construct(WePayPaymentDriver $wepay)
public function __construct(WePayPaymentDriver $wepay_payment_driver)
{
$this->wepay = $wepay;
$this->wepay_payment_driver = $wepay_payment_driver;
}
public function authorizeView($data)
{
$data['gateway'] = $this->wepay_payment_driver;
return render('gateways.wepay.authorize.bank_transfer', $data);
}
public function authorizeResponse($request)
{
//https://developer.wepay.com/api/api-calls/credit_card#authorize
$data = $request->all();
// authorize the credit card
nlog($data);
/*
'_token' => '1Fk5CRj34up5ntKPvrFyMIAJhDdUNF3boqT3iIN3',
'company_gateway_id' => '39',
'payment_method_id' => '1',
'gateway_response' => NULL,
'is_default' => NULL,
'credit_card_id' => '180642154638',
'q' => '/client/payment_methods',
'method' => '1',
*/
$response = $this->wepay_payment_driver->wepay->request('payment_bank/persist', [
'client_id' => config('ninja.wepay.client_id'),
'client_secret' => config('ninja.wepay.client_secret'),
'payment_bank_id' => (int)$data['bank_account_id'],
]);
// display the response
// nlog($response);
if(in_array($response->state, ['new', 'pending', 'authorized'])){
$this->storePaymentMethod($response, GatewayType::BANK_TRANSFER);
return redirect()->route('client.payment_methods.index');
}
throw new PaymentFailed("There was a problem adding this payment method.", 400);
/*
{
"payment_bank_id": 12345,
"bank_name": "Wells Fargo",
"account_last_four": "6789",
"state": "authorized"
}
state options: new, pending, authorized, disabled.
*/
}
/* If the bank transfer token is PENDING - we need to verify!! */
//
public function verificationView(ClientGatewayToken $token)
{
$this->wepay_payment_driver->init();
$data = [
'token' => $token,
'gateway' => $this->wepay_payment_driver,
];
return render('gateways.wepay.authorize.verify', $data);
}
/**
{
"client_id": 1234,
"client_secret": "b1fc2f68-4d1f-4a",
"payment_bank_id": 12345,
"type": "microdeposits",
"microdeposits": [
8,
12
]
}
*/
public function processVerification(Request $request, ClientGatewayToken $token)
{
$response = $this->wepay_payment_driver->wepay->request('payment_bank/verify', [
'client_id' => config('ninja.wepay.client_id'),
'client_secret' => config('ninja.wepay.client_secret'),
'payment_bank_id' => $token->token,
'type' => 'microdeposits',
'microdeposits' => $request->input('transactions'),
]);
/*
{
"payment_bank_id": 12345,
"bank_name": "Wells Fargo",
"account_last_four": "6789",
"state": "authorized"
}
*/
//$meta = $token->meta;
if($response->state == "authorized")
{
$token->routing_number = $response->state;
$token->save();
redirect()->route('client.payment_methods.index');
}
else{
redirect()->route('client.payment_methods.verification', ['id' => $token->hashed_id, 'method' => GatewayType::BANK_TRANSFER])
->withErrors(['errors', ctrans('verification_failed')]);
}
}
///////////////////////////////////////////////////////////////////////////////////////
public function paymentView(array $data)
{
$data['gateway'] = $this->wepay_payment_driver;
$data['currency'] = $this->wepay_payment_driver->client->getCurrencyCode();
$data['payment_method_id'] = GatewayType::BANK_TRANSFER;
$data['amount'] = $data['total']['amount_with_fee'];
return render('gateways.wepay.bank_transfer', $data);
}
public function paymentResponse($request)
{
nlog($request->all());
redirect()->route('client.payment_methods.verification', ['id' => $token->hashed_id, 'method' => GatewayType::BANK_TRANSFER]);
// $this->stripe->init();
// $source = ClientGatewayToken::query()
// ->where('id', $this->decodePrimaryKey($request->source))
// ->where('company_id', auth('contact')->user()->client->company->id)
// ->first();
// if (!$source) {
// throw new PaymentFailed(ctrans('texts.payment_token_not_found'), 401);
// }
// $state = [
// 'payment_method' => $request->payment_method_id,
// 'gateway_type_id' => $request->company_gateway_id,
// 'amount' => $this->stripe->convertToStripeAmount($request->amount, $this->stripe->client->currency()->precision),
// 'currency' => $request->currency,
// 'customer' => $request->customer,
// ];
// $state = array_merge($state, $request->all());
// $state['source'] = $source->token;
// $this->stripe->payment_hash->data = array_merge((array)$this->stripe->payment_hash->data, $state);
// $this->stripe->payment_hash->save();
// try {
// $state['charge'] = \Stripe\Charge::create([
// 'amount' => $state['amount'],
// 'currency' => $state['currency'],
// 'customer' => $state['customer'],
// 'source' => $state['source'],
// ], $this->stripe->stripe_connect_auth);
// $state = array_merge($state, $request->all());
// $this->stripe->payment_hash->data = array_merge((array)$this->stripe->payment_hash->data, $state);
// $this->stripe->payment_hash->save();
// if ($state['charge']->status === 'pending' && is_null($state['charge']->failure_message)) {
// return $this->processPendingPayment($state);
// }
// return $this->processUnsuccessfulPayment($state);
// } catch (Exception $e) {
// if ($e instanceof CardException) {
// return redirect()->route('client.payment_methods.verification', ['id' => ClientGatewayToken::first()->hashed_id, 'method' => GatewayType::BANK_TRANSFER]);
// }
// throw new PaymentFailed($e->getMessage(), $e->getCode());
// }
}
private function storePaymentMethod($response, $payment_method_id)
{
$payment_meta = new \stdClass;
$payment_meta->exp_month = (string) '';
$payment_meta->exp_year = (string) '';
$payment_meta->brand = (string) $response->bank_name;
$payment_meta->last4 = (string) $response->account_last_four;
$payment_meta->type = GatewayType::BANK_TRANSFER;
$data = [
'payment_meta' => $payment_meta,
'token' => $response->payment_bank_id,
'payment_method_id' => $payment_method_id,
'routing_number' => $response->state,
];
$this->wepay_payment_driver->storeGatewayToken($data);
}
}

View File

@ -57,7 +57,7 @@ class CreditCard
));
// display the response
//nlog($response);
// nlog($response);
if(in_array($response->state, ['new', 'authorized'])){

View File

@ -0,0 +1,71 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.credit_card'), 'card_title' => ctrans('texts.bank_transfer')])
@section('gateway_head')
@endsection
@section('gateway_content')
<form action="{{ route('client.payment_methods.store', ['method' => App\Models\GatewayType::BANK_TRANSFER]) }}"
method="post" id="server_response">
@csrf
<input type="hidden" name="company_gateway_id" value="{{ $gateway->company_gateway->id }}">
<input type="hidden" name="payment_method_id" value="2">
<input type="hidden" name="is_default" id="is_default">
<input type="hidden" name="bank_account_id" id="bank_account_id">
</form>
<div class="alert alert-failure mb-4" hidden id="errors"></div>
@endsection
@section('gateway_footer')
<script type="text/javascript" src="https://static.wepay.com/min/js/tokenization.4.latest.js"></script>
<script type="text/javascript">
(function() {
@if(config('ninja.wepay.environment') == 'staging')
WePay.set_endpoint("stage");
@else
WePay.set_endpoint("production");
@endif
window.onload = function(){
response = WePay.bank_account.create({
'client_id': "{{ config('ninja.wepay.client_id') }}",
'email': "{{ $contact->email }}"
}, function(data){
if(data.error) {
console.log("Pop-up closing: ")
errors.textContent = '';
errors.textContent = data.error_description;
errors.hidden = false;
} else {
// call your own app's API to save the token inside the data;
// show a success page
console.log(data);
document.querySelector('input[name="bank_account_id"]').value = data.bank_account_id;
document.getElementById('server_response').submit();
}
}, function(data){
if(data.error) {
console.log("Pop-up opening: ");
console.log(data);
// handle error response
errors.textContent = '';
errors.textContent = data.error_description;
errors.hidden = false;
} else {
// call your own app's API to save the token inside the data;
// show a success page
}
}
);
};
})();
</script>
@endsection

View File

@ -0,0 +1,24 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'ACH (Verification)', 'card_title' => 'ACH (Verification)'])
@section('gateway_content')
@if(session()->has('error'))
<div class="alert alert-failure mb-4">{{ session('error') }}</div>
@endif
<form method="POST">
@csrf
<input type="hidden" name="token" value="{{ $token->token }}">
@component('portal.ninja2020.components.general.card-element', ['title' => '#1 ' . ctrans('texts.amount')])
<input type="text" name="transactions[]" class="w-full input" required data-cy="verification-1st">
@endcomponent
@component('portal.ninja2020.components.general.card-element', ['title' => '#2 ' . ctrans('texts.amount')])
<input type="text" name="transactions[]" class="w-full input" required data-cy="verification-2nd">
@endcomponent
@component('portal.ninja2020.gateways.includes.pay_now', ['type' => 'submit'])
{{ ctrans('texts.complete_verification')}}
@endcomponent
</form>
@endsection

View File

@ -0,0 +1,47 @@
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'ACH', 'card_title' => 'ACH'])
@section('gateway_content')
@if(count($tokens) > 0)
<div class="alert alert-failure mb-4" hidden id="errors"></div>
@include('portal.ninja2020.gateways.includes.payment_details')
<form action="{{ route('client.payments.response') }}" method="post" id="server-response">
@csrf
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
<input type="hidden" name="amount" value="{{ $amount }}">
<input type="hidden" name="currency" value="{{ $currency }}">
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
<input type="hidden" name="source" value="">
</form>
@component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')])
@if(count($tokens) > 0)
@foreach($tokens as $token)
<label class="mr-4">
<input
type="radio"
data-token="{{ $token->hashed_id }}"
name="payment-type"
class="form-radio cursor-pointer toggle-payment-with-token"/>
<span class="ml-1 cursor-pointer">{{ ctrans('texts.bank_transfer') }} (*{{ $token->meta->last4 }})</span>
</label>
@endforeach
@endisset
@endcomponent
@else
@component('portal.ninja2020.components.general.card-element-single', ['title' => 'ACH', 'show_title' => false])
<span>{{ ctrans('texts.bank_account_not_linked') }}</span>
<a class="button button-link text-primary"
href="{{ route('client.payment_methods.index') }}">{{ ctrans('texts.add_payment_method') }}</a>
@endcomponent
@endif
@include('portal.ninja2020.gateways.includes.pay_now')
@endsection
@push('footer')
@endpush