From a2503f0f40654c4400982437a41b14211ee567c1 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 24 Jan 2022 21:53:46 +1100 Subject: [PATCH] Fixes for stripe payments --- .../ClientPortal/PaymentController.php | 1 + app/Models/Payment.php | 6 ++ app/PaymentDrivers/Stripe/ACSS.php | 1 - .../Stripe/Jobs/PaymentIntentWebhook.php | 76 ++++++++++++++----- app/PaymentDrivers/StripePaymentDriver.php | 8 +- 5 files changed, 71 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 0e42d64f47..9e65b6c3c8 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -90,6 +90,7 @@ class PaymentController extends Controller public function response(PaymentResponseRequest $request) { + $gateway = CompanyGateway::findOrFail($request->input('company_gateway_id')); $payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->payment_hash])->first(); diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 183a6d0a91..5465f9cd06 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -13,6 +13,7 @@ namespace App\Models; use App\Events\Payment\PaymentWasRefunded; use App\Events\Payment\PaymentWasVoided; +use App\Models\GatewayType; use App\Services\Ledger\LedgerService; use App\Services\Payment\PaymentService; use App\Utils\Ninja; @@ -148,6 +149,11 @@ class Payment extends BaseModel return $this->belongsTo(PaymentType::class); } + public function gateway_type() + { + return $this->belongsTo(GatewayType::class); + } + public function paymentables() { return $this->hasMany(Paymentable::class); diff --git a/app/PaymentDrivers/Stripe/ACSS.php b/app/PaymentDrivers/Stripe/ACSS.php index 63867db54d..cab2b57113 100644 --- a/app/PaymentDrivers/Stripe/ACSS.php +++ b/app/PaymentDrivers/Stripe/ACSS.php @@ -154,7 +154,6 @@ class ACSS 'interval_description' => 'when any invoice becomes due', 'transaction_type' => 'personal' // TODO: check if is company or personal https://stripe.com/docs/payments/acss-debit ], - 'currency' => $this->stripe->client->currency()->code, ] ] ], $this->stripe->stripe_connect_auth); diff --git a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php index d4fdb9dce4..f621e923d2 100644 --- a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php +++ b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php @@ -42,6 +42,8 @@ class PaymentIntentWebhook implements ShouldQueue private $company_gateway_id; + public $payment_completed = false; + public function __construct($stripe_request, $company_key, $company_gateway_id) { $this->stripe_request = $stripe_request; @@ -51,39 +53,79 @@ class PaymentIntentWebhook implements ShouldQueue public function handle() { - - // nlog(optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata'])['gateway_type_id']); - // nlog(optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata'])['payment_hash']); - // nlog(optional($this->stripe_request['data']['object']['charges']['data'][0]['payment_method_details']['card'])['brand']); + // nlog($this->stripe_request); + // nlog(optional($this->stripe_request['object']['charges']['data'][0]['metadata'])['gateway_type_id']); + // nlog(optional($this->stripe_request['object']['charges']['data'][0]['metadata'])['payment_hash']); + // nlog(optional($this->stripe_request['object']['charges']['data'][0]['payment_method_details']['card'])['brand']); MultiDB::findAndSetDbByCompanyKey($this->company_key); - if(optional($this->stripe_request['data']['object']['charges']['data'][0])['id']){ + $company = Company::where('company_key', $this->company_key)->first(); + + foreach ($this->stripe_request as $transaction) { + + if(array_key_exists('payment_intent', $transaction)) + { + $payment = Payment::query() + ->where('company_id', $company->id) + ->where(function ($query) use ($transaction) { + $query->where('transaction_reference', $transaction['payment_intent']) + ->orWhere('transaction_reference', $transaction['id']); + }) + ->first(); + } + else + { + $payment = Payment::query() + ->where('company_id', $company->id) + ->where('transaction_reference', $transaction['id']) + ->first(); + } + + if ($payment) { + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->save(); + + $this->payment_completed = true; + } + } + + + if($this->payment_completed) + return; + + + if(optional($this->stripe_request['object']['charges']['data'][0])['id']){ $company = Company::where('company_key', $this->company_key)->first(); $payment = Payment::query() ->where('company_id', $company->id) - ->where('transaction_reference', $this->stripe_request['data']['object']['charges']['data'][0]['id']) + ->where('transaction_reference', $this->stripe_request['object']['charges']['data'][0]['id']) ->first(); //return early - if($payment && $payment->status_id == Payment::STATUS_COMPLETED){ + if($payment && $payment->status_id == Payment::STATUS_COMPLETED){ nlog(" payment found and status correct - returning "); return; } + elseif($payment){ + $payment->status_id = Payment::STATUS_COMPLETED; + $payment->save(); + } - $hash = optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata'])['payment_hash']; + + $hash = optional($this->stripe_request['object']['charges']['data'][0]['metadata'])['payment_hash']; $payment_hash = PaymentHash::where('hash', $hash)->first(); nlog("no payment found"); - if(optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata']['payment_hash'])) + if(optional($this->stripe_request['object']['charges']['data'][0]['metadata']['payment_hash']) && in_array('card', $this->stripe_request['object']['allowed_source_types'])) { nlog("hash found"); - $hash = $this->stripe_request['data']['object']['charges']['data'][0]['metadata']['payment_hash']; + $hash = $this->stripe_request['object']['charges']['data'][0]['metadata']['payment_hash']; $payment_hash = PaymentHash::where('hash', $hash)->first(); $invoice = Invoice::with('client')->find($payment_hash->fee_invoice_id); @@ -99,7 +141,7 @@ class PaymentIntentWebhook implements ShouldQueue private function updateCreditCardPayment($payment_hash, $client) { $company_gateway = CompanyGateway::find($this->company_gateway_id); - $payment_method_type = optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata'])['gateway_type_id']; + $payment_method_type = optional($this->stripe_request['object']['charges']['data'][0]['metadata'])['gateway_type_id']; $driver = $company_gateway->driver($client)->init()->setPaymentMethod($payment_method_type); $payment_hash->data = array_merge((array) $payment_hash->data, $this->stripe_request); @@ -107,10 +149,10 @@ class PaymentIntentWebhook implements ShouldQueue $driver->setPaymentHash($payment_hash); $data = [ - 'payment_method' => $payment_hash->data->data->object->payment_method, - 'payment_type' => PaymentType::parseCardType(strtolower(optional($this->stripe_request['data']['object']['charges']['data'][0]['payment_method_details']['card'])['brand'])) ?: PaymentType::CREDIT_CARD_OTHER, + 'payment_method' => $payment_hash->data->object->payment_method, + 'payment_type' => PaymentType::parseCardType(strtolower(optional($this->stripe_request['object']['charges']['data'][0]['payment_method_details']['card'])['brand'])) ?: PaymentType::CREDIT_CARD_OTHER, 'amount' => $payment_hash->data->amount_with_fee, - 'transaction_reference' => $this->stripe_request['data']['object']['charges']['data'][0]['id'], + 'transaction_reference' => $this->stripe_request['object']['charges']['data'][0]['id'], 'gateway_type_id' => GatewayType::CREDIT_CARD, ]; @@ -127,9 +169,9 @@ class PaymentIntentWebhook implements ShouldQueue } - //charge # optional($this->stripe_request['data']['object']['charges']['data'][0])['id'] - //metadata # optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata']['gateway_type_id'] - //metadata # optional($this->stripe_request['data']['object']['charges']['data'][0]['metadata']['payment_hash'] + //charge # optional($this->stripe_request['object']['charges']['data'][0])['id'] + //metadata # optional($this->stripe_request['object']['charges']['data'][0]['metadata']['gateway_type_id'] + //metadata # optional($this->stripe_request['object']['charges']['data'][0]['metadata']['payment_hash'] /** diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 6c2a1b1c77..7d0ed85771 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -532,12 +532,13 @@ class StripePaymentDriver extends BaseDriver //payment_intent.succeeded - this will confirm or cancel the payment if($request->type === 'payment_intent.succeeded'){ - PaymentIntentWebhook::dispatch($request->all(), $request->company_key, $this->company_gateway->id)->delay(10); - // PaymentIntentWebhook::dispatch($request->all(), $request->company_key, $this->company_gateway->id); + PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id)->delay(10); + // PaymentIntentWebhook::dispatch($request->data, $request->company_key, $this->company_gateway->id); return response()->json([], 200); } - if ($request->type === 'charge.succeeded' || $request->type === 'payment_intent.succeeded') { + if ($request->type === 'charge.succeeded') { + // if ($request->type === 'charge.succeeded' || $request->type === 'payment_intent.succeeded') { foreach ($request->data as $transaction) { @@ -564,6 +565,7 @@ class StripePaymentDriver extends BaseDriver $payment->save(); } } + } elseif ($request->type === 'source.chargeable') { $this->init();