mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
WePay authorize for Bank Transfer
This commit is contained in:
parent
d4f27bb3ee
commit
43ff685543
@ -41,4 +41,35 @@ class InvoicePresenter extends EntityPresenter
|
|||||||
return '';
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,20 +12,245 @@
|
|||||||
|
|
||||||
namespace App\PaymentDrivers\WePay;
|
namespace App\PaymentDrivers\WePay;
|
||||||
|
|
||||||
|
use App\Exceptions\PaymentFailed;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use App\Models\ClientGatewayToken;
|
||||||
|
use App\Models\GatewayType;
|
||||||
use App\PaymentDrivers\WePayPaymentDriver;
|
use App\PaymentDrivers\WePayPaymentDriver;
|
||||||
|
|
||||||
class ACH
|
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)
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class CreditCard
|
|||||||
));
|
));
|
||||||
|
|
||||||
// display the response
|
// display the response
|
||||||
//nlog($response);
|
// nlog($response);
|
||||||
|
|
||||||
if(in_array($response->state, ['new', 'authorized'])){
|
if(in_array($response->state, ['new', 'authorized'])){
|
||||||
|
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user