From 9bec6d458b7d871096072613845680a59bae190d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 6 Oct 2022 10:12:57 +1100 Subject: [PATCH] Improve Stripe ACH Payments with microdeposits --- app/PaymentDrivers/Stripe/ACH.php | 17 +++++++ .../Stripe/Jobs/PaymentIntentWebhook.php | 46 ++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/PaymentDrivers/Stripe/ACH.php b/app/PaymentDrivers/Stripe/ACH.php index d602d320f0c9..2a5689ccf901 100644 --- a/app/PaymentDrivers/Stripe/ACH.php +++ b/app/PaymentDrivers/Stripe/ACH.php @@ -165,6 +165,18 @@ class ACH $data['payment_method_id'] = GatewayType::BANK_TRANSFER; $data['customer'] = $this->stripe->findOrCreateCustomer(); $data['amount'] = $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()); + $amount = $data['total']['amount_with_fee']; + + $invoice = Invoice::whereIn('id', $this->transformKeys(array_column($this->stripe->payment_hash->invoices(), 'invoice_id'))) + ->withTrashed() + ->first(); + + if ($invoice) { + $description = "Invoice {$invoice->number} for {$amount} for client {$this->stripe->client->present()->name()}"; + } else { + $description = "Payment with no invoice for amount {$amount} for client {$this->stripe->client->present()->name()}"; + } + $intent = false; @@ -176,6 +188,11 @@ class ACH 'setup_future_usage' => 'off_session', 'customer' => $data['customer']->id, 'payment_method_types' => ['us_bank_account'], + 'description' => $description, + 'metadata' => [ + 'payment_hash' => $this->stripe->payment_hash->hash, + 'gateway_type_id' => GatewayType::BANK_TRANSFER, + ], ] ); } diff --git a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php index f37f46f5a7b3..800f13f9f86b 100644 --- a/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php +++ b/app/PaymentDrivers/Stripe/Jobs/PaymentIntentWebhook.php @@ -53,7 +53,8 @@ class PaymentIntentWebhook implements ShouldQueue public function handle() { - + nlog($this->stripe_request); + MultiDB::findAndSetDbByCompanyKey($this->company_key); $company = Company::where('company_key', $this->company_key)->first(); @@ -145,7 +146,18 @@ class PaymentIntentWebhook implements ShouldQueue $this->updateCreditCardPayment($payment_hash, $client); } + elseif(array_key_exists('payment_method_types', $this->stripe_request['object']) && optional($this->stripe_request['object']['charges']['data'][0]['metadata']['payment_hash']) && in_array('us_bank_account', $this->stripe_request['object']['payment_method_types'])) + { + nlog("hash found"); + $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); + $client = $invoice->client; + + $this->updateAchPayment($payment_hash, $client); + } } @@ -161,6 +173,38 @@ class PaymentIntentWebhook implements ShouldQueue } + private function updateAchPayment($payment_hash, $client) + { + $company_gateway = CompanyGateway::find($this->company_gateway_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); + $payment_hash->save(); + $driver->setPaymentHash($payment_hash); + + $data = [ + 'payment_method' => $payment_hash->data->object->payment_method, + 'payment_type' => PaymentType::ACH, + 'amount' => $payment_hash->data->amount_with_fee, + 'transaction_reference' => $this->stripe_request['object']['charges']['data'][0]['id'], + 'gateway_type_id' => GatewayType::BANK_TRANSFER, + ]; + + $payment = $driver->createPayment($data, Payment::STATUS_COMPLETED); + + SystemLogger::dispatch( + ['response' => $this->stripe_request, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_STRIPE, + $client, + $client->company, + ); + + } + + private function updateCreditCardPayment($payment_hash, $client) { $company_gateway = CompanyGateway::find($this->company_gateway_id);