From 3de9c99d34cf3d6d56e0c7933e4c293bb3d53c3b Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 14:26:13 +1000 Subject: [PATCH 01/33] powerboard --- app/Models/CompanyGateway.php | 1 + app/Models/Gateway.php | 4 + app/Models/SystemLog.php | 2 + .../CBAPowerBoard/CreditCard.php | 215 ++++++++++++++++++ .../CBAPowerBoardPaymentDriver.php | 134 +++++++++++ .../2024_09_06_042040_cba_powerboard.php | 45 ++++ database/seeders/PaymentLibrariesSeeder.php | 3 +- 7 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 app/PaymentDrivers/CBAPowerBoard/CreditCard.php create mode 100644 app/PaymentDrivers/CBAPowerBoardPaymentDriver.php create mode 100644 database/migrations/2024_09_06_042040_cba_powerboard.php diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index ce561f31bf0c..f8ff6118490f 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -156,6 +156,7 @@ class CompanyGateway extends BaseModel '80af24a6a691230bbec33e930ab40666' => 323, 'vpyfbmdrkqcicpkjqdusgjfluebftuva' => 324, //BTPay '91be24c7b792230bced33e930ac61676' => 325, + 'b67581d804dbad1743b61c57285142ad' => 326, //Powerboard ]; protected $touches = []; diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 1bbfe1b95fae..51537dc1901f 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -235,6 +235,10 @@ class Gateway extends StaticModel ], GatewayType::ACSS => ['refund' => false, 'token_billing' => true, 'webhooks' => []] ]; // Rotessa + case 64: //b67581d804dbad1743b61c57285142ad - powerboard + return [ + + ] default: return []; } diff --git a/app/Models/SystemLog.php b/app/Models/SystemLog.php index 10eb1f2629a8..6632acce6fe3 100644 --- a/app/Models/SystemLog.php +++ b/app/Models/SystemLog.php @@ -154,6 +154,8 @@ class SystemLog extends Model public const TYPE_ROTESSA = 325; + public const TYPE_POWERBOARD = 326; + public const TYPE_QUOTA_EXCEEDED = 400; public const TYPE_UPSTREAM_FAILURE = 401; diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php new file mode 100644 index 000000000000..75b3e923907c --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -0,0 +1,215 @@ +stripe->getSetupIntent(); + + return render('gateways.powerboard.credit_card.authorize', array_merge($data, $intent)); + } + + public function authorizeResponse($request) + { + $this->stripe->init(); + + // $stripe_response = json_decode($request->input('gateway_response')); + + $customer = $this->powerboard->findOrCreateCustomer(); + + // $this->stripe->attach($stripe_response->payment_method, $customer); + + // $stripe_method = $this->stripe->getStripePaymentMethod($stripe_response->payment_method); + + // $this->storePaymentMethod($stripe_method, $request->payment_method_id, $customer); + + return redirect()->route('client.payment_methods.index'); + } + + public function paymentData(array $data): array + { + // $description = $this->stripe->getDescription(false); + + // $payment_intent_data = [ + // 'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()), + // 'currency' => $this->stripe->client->getCurrencyCode(), + // 'customer' => $this->stripe->findOrCreateCustomer(), + // 'description' => $description, + // 'metadata' => [ + // 'payment_hash' => $this->stripe->payment_hash->hash, + // 'gateway_type_id' => GatewayType::CREDIT_CARD, + // ], + // 'setup_future_usage' => 'off_session', + // 'payment_method_types' => ['card'], + // ]; + + // $data['intent'] = $this->stripe->createPaymentIntent($payment_intent_data); + // $data['gateway'] = $this->stripe; + + // return $data; + } + + public function paymentView(array $data) + { + $data = $this->paymentData($data); + + return render('gateways.stripe.credit_card.pay', $data); + } + + public function livewirePaymentView(array $data): string + { + return 'gateways.powerboard.credit_card.pay_livewire'; + } + + public function paymentResponse(PaymentResponseRequest $request) + { + // $this->stripe->init(); + + // $state = [ + // 'server_response' => json_decode($request->gateway_response), + // 'payment_hash' => $request->payment_hash, + // ]; + + // $state = array_merge($state, $request->all()); + // $state['store_card'] = boolval($state['store_card']); + + // if ($request->has('token') && ! is_null($request->token)) { + // $state['store_card'] = false; + // } + + // $state['payment_intent'] = PaymentIntent::retrieve($state['server_response']->id, array_merge($this->stripe->stripe_connect_auth, ['idempotency_key' => uniqid("st", true)])); + // $state['customer'] = $state['payment_intent']->customer; + + // $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, $state); + // $this->stripe->payment_hash->save(); + + // $server_response = $this->stripe->payment_hash->data->server_response; + + // if ($server_response->status == 'succeeded') { + // $this->stripe->logSuccessfulGatewayResponse(['response' => json_decode($request->gateway_response), 'data' => $this->stripe->payment_hash], SystemLog::TYPE_STRIPE); + + // return $this->processSuccessfulPayment(); + // } + + // return $this->processUnsuccessfulPayment($server_response); + } + + public function processSuccessfulPayment() + { + // UpdateCustomer::dispatch($this->stripe->company_gateway->company->company_key, $this->stripe->company_gateway->id, $this->stripe->client->id); + + // $stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method); + + // $data = [ + // 'payment_method' => $this->stripe->payment_hash->data->server_response->payment_method, + // 'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)) ?: PaymentType::CREDIT_CARD_OTHER, + // 'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()), + // 'transaction_reference' => isset($this->stripe->payment_hash->data->payment_intent->latest_charge) ? $this->stripe->payment_hash->data->payment_intent->latest_charge : optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id, + // 'gateway_type_id' => GatewayType::CREDIT_CARD, + // ]; + + // $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['amount' => $data['amount']]); + // $this->stripe->payment_hash->save(); + + // if ($this->stripe->payment_hash->data->store_card) { + // $customer = new \stdClass(); + // $customer->id = $this->stripe->payment_hash->data->customer; + + // $this->stripe->attach($this->stripe->payment_hash->data->server_response->payment_method, $customer); + + // $stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method); + + // $this->storePaymentMethod($stripe_method, $this->stripe->payment_hash->data->payment_method_id, $customer); + // } + + // $payment = $this->stripe->createPayment($data, Payment::STATUS_COMPLETED); + + // SystemLogger::dispatch( + // ['response' => $this->stripe->payment_hash->data->server_response, 'data' => $data], + // SystemLog::CATEGORY_GATEWAY_RESPONSE, + // SystemLog::EVENT_GATEWAY_SUCCESS, + // SystemLog::TYPE_STRIPE, + // $this->stripe->client, + // $this->stripe->client->company, + // ); + + // if ($payment->invoices()->whereHas('subscription')->exists()) { + // $subscription = $payment->invoices()->first()->subscription; + + // if ($subscription && array_key_exists('return_url', $subscription->webhook_configuration) && strlen($subscription->webhook_configuration['return_url']) >= 1) { + // return redirect($subscription->webhook_configuration['return_url']); + // } + // } + + // return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + } + + public function processUnsuccessfulPayment($server_response) + { + // $this->stripe->sendFailureMail($server_response->cancellation_reason); + + // $message = [ + // 'server_response' => $server_response, + // 'data' => $this->stripe->payment_hash->data, + // ]; + + // SystemLogger::dispatch( + // $message, + // SystemLog::CATEGORY_GATEWAY_RESPONSE, + // SystemLog::EVENT_GATEWAY_FAILURE, + // SystemLog::TYPE_STRIPE, + // $this->stripe->client, + // $this->stripe->client->company, + // ); + + // throw new PaymentFailed('Failed to process the payment.', 500); + } + + private function storePaymentMethod($method, $payment_method_id, $customer) + { + // try { + // $payment_meta = new \stdClass(); + // $payment_meta->exp_month = (string) $method->card->exp_month; + // $payment_meta->exp_year = (string) $method->card->exp_year; + // $payment_meta->brand = (string) $method->card->brand; + // $payment_meta->last4 = (string) $method->card->last4; + // $payment_meta->type = GatewayType::CREDIT_CARD; + + // $data = [ + // 'payment_meta' => $payment_meta, + // 'token' => $method->id, + // 'payment_method_id' => $payment_method_id, + // ]; + + // $this->stripe->storeGatewayToken($data, ['gateway_customer_reference' => $customer->id]); + // } catch (\Exception $e) { + // return $this->stripe->processInternallyFailedPayment($this->stripe, $e); + // } + } +} diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php new file mode 100644 index 000000000000..b0fa1ddd7c22 --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -0,0 +1,134 @@ +company_gateway->getConfigField('account_id') + + return $this; + } + + public function setPaymentMethod($payment_method_id) + { + $this->payment_method = $payment_method_id; + + return $this; + } + + /** + * View for displaying custom content of the driver. + * + * @param array $data + * @return mixed + */ + public function processPaymentView($data) + { + return $this->payment_method->paymentView($data); + } + + /** + * Processing method for payment. Should never be reached with this driver. + * + * @return mixed + */ + public function processPaymentResponse($request) + { + return $this->payment_method->paymentResponse($request); + } + + /** + * Detach payment method from custom payment driver. + * + * @param ClientGatewayToken $token + * @return void + */ + public function detach(ClientGatewayToken $token) + { + // Driver doesn't support this feature. + } + + public function refund(Payment $payment, $amount, $return_client_response = false) + { + + } + + public function processWebhookRequest($request) + { + } + + public function getClientRequiredFields(): array + { + return []; + } + + public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) + { + return (new Charge($this))->tokenBilling($cgt, $payment_hash); + } + + public function importCustomers() + { + } + + public function auth(): bool + { + $this->init(); + + // try { + // $this->verifyConnect(); + // return true; + // } catch(\Exception $e) { + + // } + + // return false; + + } +} diff --git a/database/migrations/2024_09_06_042040_cba_powerboard.php b/database/migrations/2024_09_06_042040_cba_powerboard.php new file mode 100644 index 000000000000..b48c0de579ba --- /dev/null +++ b/database/migrations/2024_09_06_042040_cba_powerboard.php @@ -0,0 +1,45 @@ +accessToken = ''; + // $fields->applicationId = ''; + // $fields->locationId = ''; + $fields->testMode = false; + + $powerboard = new Gateway(); + $powerboard->id = 64; + $powerboard->name = 'CBA PowerBoard'; + $powerboard->provider = 'CBAPowerBoard'; + $powerboard->key = 'b67581d804dbad1743b61c57285142ad'; + $powerboard->sort_order = 4543; + $powerboard->is_offsite = false; + $powerboard->visible = true; + $powerboard->fields = json_encode($fields); + $powerboard->save(); + + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index 49c49e87b44e..50911bb3b7e3 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -88,7 +88,8 @@ class PaymentLibrariesSeeder extends Seeder ['id' => 60, 'name' => 'PayPal REST', 'provider' => 'PayPal_Rest', 'key' => '80af24a6a691230bbec33e930ab40665', 'fields' => '{"clientId":"","secret":"","signature":"","testMode":false}'], ['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'], ['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey":"", "storeId":"", "webhookSecret":""}'], - ['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":""}'], + ['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":false}'], + ['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"accessToken":"", "testMode":false}'], ]; foreach ($gateways as $gateway) { From 30ff4909770b4354e0750cb648314506bed8bf4f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 14:34:54 +1000 Subject: [PATCH 02/33] powerboard --- app/PaymentDrivers/CBAPowerBoardPaymentDriver.php | 3 +++ database/migrations/2024_09_06_042040_cba_powerboard.php | 4 +++- database/seeders/PaymentLibrariesSeeder.php | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index b0fa1ddd7c22..e419d33bb5f9 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -36,6 +36,9 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public $refundable = true; + protected $api_endpoint = ''; + + protected $widget_endpoint = ''; /** * Returns the gateway types. */ diff --git a/database/migrations/2024_09_06_042040_cba_powerboard.php b/database/migrations/2024_09_06_042040_cba_powerboard.php index b48c0de579ba..d4e756672546 100644 --- a/database/migrations/2024_09_06_042040_cba_powerboard.php +++ b/database/migrations/2024_09_06_042040_cba_powerboard.php @@ -17,7 +17,9 @@ return new class extends Migration Model::unguard(); $fields = new \stdClass(); - $fields->accessToken = ''; + + $fields->publicKey = ''; + $fields->secretKey = ''; // $fields->applicationId = ''; // $fields->locationId = ''; $fields->testMode = false; diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index 50911bb3b7e3..f77761e5acb7 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -89,7 +89,7 @@ class PaymentLibrariesSeeder extends Seeder ['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'], ['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey":"", "storeId":"", "webhookSecret":""}'], ['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":false}'], - ['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"accessToken":"", "testMode":false}'], + ['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"publicKey":"", "secretKey":"", "testMode":false}'], ]; foreach ($gateways as $gateway) { From 54c18312286db60901d01eb2d475a2917500439e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 15:15:33 +1000 Subject: [PATCH 03/33] Powerboard --- .../CBAPowerBoard/CreditCard.php | 6 ++-- .../CBAPowerBoardPaymentDriver.php | 28 ++++++++++++------- .../gateways/powerboard/pay.blade.php | 10 +++++++ 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 75b3e923907c..3207497f3c8c 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -55,7 +55,9 @@ class CreditCard implements LivewireMethodInterface public function paymentData(array $data): array { // $description = $this->stripe->getDescription(false); - + $merge = [ + 'publicKey' => $this->powerboard->company_gateway->getConfigField('publicKey'), + ]; // $payment_intent_data = [ // 'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()), // 'currency' => $this->stripe->client->getCurrencyCode(), @@ -72,7 +74,7 @@ class CreditCard implements LivewireMethodInterface // $data['intent'] = $this->stripe->createPaymentIntent($payment_intent_data); // $data['gateway'] = $this->stripe; - // return $data; + return array_merge($data, $merge); } public function paymentView(array $data) diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index e419d33bb5f9..27583f6a69ed 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -12,16 +12,17 @@ namespace App\PaymentDrivers; -use App\Jobs\Util\SystemLogger; -use App\Models\ClientGatewayToken; -use App\Models\GatewayType; use App\Models\Invoice; use App\Models\Payment; -use App\Models\PaymentHash; -use App\Models\PaymentType; use App\Models\SystemLog; use App\Utils\HtmlEngine; +use App\Models\GatewayType; +use App\Models\PaymentHash; +use App\Models\PaymentType; +use App\Jobs\Util\SystemLogger; use App\Utils\Traits\MakesHash; +use App\Models\ClientGatewayToken; +use App\PaymentDrivers\CBAPowerBoard\CreditCard; /** * Class CBAPowerBoardPaymentDriver. @@ -36,9 +37,13 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public $refundable = true; - protected $api_endpoint = ''; + protected $api_endpoint = 'https://api.powerboard.commbank.com.au/'; - protected $widget_endpoint = ''; + protected $widget_endpoint = 'https://widget.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; + + public static $methods = [ + GatewayType::CREDIT_CARD => CreditCard::class, + ]; /** * Returns the gateway types. */ @@ -51,9 +56,11 @@ class CBAPowerBoardPaymentDriver extends BaseDriver return $types; } - public function init() + public function init(): self { -// $this->company_gateway->getConfigField('account_id') + if($this->company_gateway->getConfigField('testMode')) { + $this->widget_endpoint = 'https://widget.preproduction.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; + $this->api_endpoint = 'https://api.preproduction.powerboard.commbank.com.au/'; } return $this; } @@ -113,7 +120,6 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public function tokenBilling(ClientGatewayToken $cgt, PaymentHash $payment_hash) { - return (new Charge($this))->tokenBilling($cgt, $payment_hash); } public function importCustomers() @@ -124,6 +130,8 @@ class CBAPowerBoardPaymentDriver extends BaseDriver { $this->init(); + + return true; // try { // $this->verifyConnect(); // return true; diff --git a/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php new file mode 100644 index 000000000000..b41083273dc0 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php @@ -0,0 +1,10 @@ + + + + + +
\ No newline at end of file From 454f7df01e88353efa40774057f4f76c1445813e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 18:31:00 +1000 Subject: [PATCH 04/33] Powerboard --- app/Livewire/Flow2/InvoiceSummary.php | 7 +- app/Models/Gateway.php | 4 +- .../CBAPowerBoard/CreditCard.php | 9 +- .../CBAPowerBoardPaymentDriver.php | 17 +- .../powerboard/credit_card/pay.blade.php | 150 ++++++++++++++++++ .../gateways/powerboard/pay.blade.php | 10 -- 6 files changed, 173 insertions(+), 24 deletions(-) create mode 100644 resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php delete mode 100644 resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php diff --git a/app/Livewire/Flow2/InvoiceSummary.php b/app/Livewire/Flow2/InvoiceSummary.php index af21a26894a6..f856ab52e3e7 100644 --- a/app/Livewire/Flow2/InvoiceSummary.php +++ b/app/Livewire/Flow2/InvoiceSummary.php @@ -50,7 +50,7 @@ class InvoiceSummary extends Component public function downloadDocument($invoice_hashed_id) { - nlog("here"); + $contact = $this->getContext()['contact']; $_invoices = $this->getContext()['invoices']; $i = $_invoices->first(function ($i) use($invoice_hashed_id){ @@ -61,11 +61,6 @@ class InvoiceSummary extends Component $file = (new \App\Jobs\Entity\CreateRawPdf($i->invitations()->where('client_contact_id', $contact->id)->first()))->handle(); - - nlog("here"); - - nlog($file); - $headers = ['Content-Type' => 'application/pdf']; return response()->streamDownload(function () use ($file) { diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 51537dc1901f..d1276d931348 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -237,8 +237,8 @@ class Gateway extends StaticModel ]; // Rotessa case 64: //b67581d804dbad1743b61c57285142ad - powerboard return [ - - ] + GatewayType::CREDIT_CARD => ['refund' => true, 'token_billing' => true], + ]; default: return []; } diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 3207497f3c8c..f8ef176e991a 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -56,7 +56,10 @@ class CreditCard implements LivewireMethodInterface { // $description = $this->stripe->getDescription(false); $merge = [ - 'publicKey' => $this->powerboard->company_gateway->getConfigField('publicKey'), + 'public_key' => $this->powerboard->company_gateway->getConfigField('publicKey'), + 'widget_endpoint' => $this->powerboard->widget_endpoint, + 'gateway' => $this->powerboard, + 'environment' => $this->powerboard->environment, ]; // $payment_intent_data = [ // 'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()), @@ -81,7 +84,7 @@ class CreditCard implements LivewireMethodInterface { $data = $this->paymentData($data); - return render('gateways.stripe.credit_card.pay', $data); + return render('gateways.powerboard.credit_card.pay', $data); } public function livewirePaymentView(array $data): string @@ -91,6 +94,8 @@ class CreditCard implements LivewireMethodInterface public function paymentResponse(PaymentResponseRequest $request) { + nlog($request->all()); + // $this->stripe->init(); // $state = [ diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index 27583f6a69ed..a14c294b117a 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -37,9 +37,11 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public $refundable = true; - protected $api_endpoint = 'https://api.powerboard.commbank.com.au/'; + public string $api_endpoint = 'https://api.powerboard.commbank.com.au/'; - protected $widget_endpoint = 'https://widget.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; + public string $widget_endpoint = 'https://widget.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; + + public string $environment = 'production_cba'; public static $methods = [ GatewayType::CREDIT_CARD => CreditCard::class, @@ -60,14 +62,19 @@ class CBAPowerBoardPaymentDriver extends BaseDriver { if($this->company_gateway->getConfigField('testMode')) { $this->widget_endpoint = 'https://widget.preproduction.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; - $this->api_endpoint = 'https://api.preproduction.powerboard.commbank.com.au/'; } + $this->api_endpoint = 'https://api.preproduction.powerboard.commbank.com.au/'; + $this->environment = 'preproduction_cba'; + } return $this; } public function setPaymentMethod($payment_method_id) { - $this->payment_method = $payment_method_id; + + $class = self::$methods[$payment_method_id]; + + $this->payment_method = new $class($this); return $this; } @@ -80,6 +87,8 @@ class CBAPowerBoardPaymentDriver extends BaseDriver */ public function processPaymentView($data) { + $this->init(); + return $this->payment_method->paymentView($data); } diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php new file mode 100644 index 000000000000..35dc0680f9c4 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -0,0 +1,150 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Credit card', 'card_title' => 'Credit card']) + +@section('gateway_head') + +@endsection + +@section('gateway_content') + +
+ @csrf + + + + + + + + + +
+ + + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')]) + {{ ctrans('texts.credit_card') }} + @endcomponent + + @include('portal.ninja2020.gateways.includes.payment_details') + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) +
    + @if(count($tokens) > 0) + @foreach($tokens as $token) +
  • + +
  • + @endforeach + @endisset + +
  • + +
  • +
+ + + @endcomponent + +
+
+
+ @include('portal.ninja2020.gateways.includes.pay_now') + +@endsection + +@section('gateway_footer') + + + + + + + +@endsection + + + diff --git a/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php deleted file mode 100644 index b41083273dc0..000000000000 --- a/resources/views/portal/ninja2020/gateways/powerboard/pay.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - - - - - -
\ No newline at end of file From 6876a647caa736ed618ad3e85554c8a645e7a06d Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 19:15:08 +1000 Subject: [PATCH 05/33] powerboard --- .../CBAPowerBoard/CreditCard.php | 35 ++++++++----------- .../CBAPowerBoardPaymentDriver.php | 20 +++++++++-- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index f8ef176e991a..fb2e8e14329e 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -30,18 +30,27 @@ class CreditCard implements LivewireMethodInterface public function authorizeView(array $data) { - $intent['intent'] = $this->stripe->getSetupIntent(); - return render('gateways.powerboard.credit_card.authorize', array_merge($data, $intent)); + return render('gateways.powerboard.credit_card.authorize', array_merge($data, [])); } public function authorizeResponse($request) { - $this->stripe->init(); + $this->powerboard->init(); + + $payment_source = $request->gateway_response; + + $payload = [ + 'token' => $payment_source, + + ]; + + $this->powerboard->gatewayRequest('/v1/vault/payment_sources', 'post', $payload, []); + // $stripe_response = json_decode($request->input('gateway_response')); - $customer = $this->powerboard->findOrCreateCustomer(); + // $customer = $this->powerboard->findOrCreateCustomer(); // $this->stripe->attach($stripe_response->payment_method, $customer); @@ -61,22 +70,8 @@ class CreditCard implements LivewireMethodInterface 'gateway' => $this->powerboard, 'environment' => $this->powerboard->environment, ]; - // $payment_intent_data = [ - // 'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()), - // 'currency' => $this->stripe->client->getCurrencyCode(), - // 'customer' => $this->stripe->findOrCreateCustomer(), - // 'description' => $description, - // 'metadata' => [ - // 'payment_hash' => $this->stripe->payment_hash->hash, - // 'gateway_type_id' => GatewayType::CREDIT_CARD, - // ], - // 'setup_future_usage' => 'off_session', - // 'payment_method_types' => ['card'], - // ]; - - // $data['intent'] = $this->stripe->createPaymentIntent($payment_intent_data); - // $data['gateway'] = $this->stripe; + return array_merge($data, $merge); } @@ -95,7 +90,7 @@ class CreditCard implements LivewireMethodInterface public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); - + // $this->stripe->init(); // $state = [ diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index a14c294b117a..6e005e6d3bfd 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -37,7 +37,7 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public $refundable = true; - public string $api_endpoint = 'https://api.powerboard.commbank.com.au/'; + public string $api_endpoint = 'https://api.powerboard.commbank.com.au'; public string $widget_endpoint = 'https://widget.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; @@ -62,7 +62,7 @@ class CBAPowerBoardPaymentDriver extends BaseDriver { if($this->company_gateway->getConfigField('testMode')) { $this->widget_endpoint = 'https://widget.preproduction.powerboard.commbank.com.au/sdk/latest/widget.umd.min.js'; - $this->api_endpoint = 'https://api.preproduction.powerboard.commbank.com.au/'; + $this->api_endpoint = 'https://api.preproduction.powerboard.commbank.com.au'; $this->environment = 'preproduction_cba'; } @@ -151,4 +151,20 @@ class CBAPowerBoardPaymentDriver extends BaseDriver // return false; } + + public function gatewayRequest(string $uri, string $verb, array $payload, array $headers = []) + { + $r = Http::withHeaders($this->getHeaders($headers)) + ->{$verb}($this->api_endpoint.$uri, $payload); + } + + public function getHeaders(array $headers = []): array + { + return array_merge([ + 'x-user-secret-key' => $this->company_gateway->getConfigField('secretKey'), + 'Content-Type' => 'application/json', + ], + $headers); + } + } From 734878a73d51ca60a37a497a8e5a8be2742710bb Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 22:55:56 +1000 Subject: [PATCH 06/33] powerboard --- .../CBAPowerBoard/CreditCard.php | 106 ++++++++++++------ .../CBAPowerBoardPaymentDriver.php | 3 +- .../powerboard/credit_card/pay.blade.php | 19 +++- 3 files changed, 90 insertions(+), 38 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index fb2e8e14329e..17c1913041bf 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -31,7 +31,7 @@ class CreditCard implements LivewireMethodInterface public function authorizeView(array $data) { - return render('gateways.powerboard.credit_card.authorize', array_merge($data, [])); + return render('gateways.powerboard.credit_card.authorize', $this->paymentData($data)); } public function authorizeResponse($request) @@ -42,28 +42,92 @@ class CreditCard implements LivewireMethodInterface $payload = [ 'token' => $payment_source, - + 'first_name' => $this->powerboard->client->present()->first_name(), + 'last_name' => $this->powerboard->client->present()->first_name(), + 'email' => $this->powerboard->client->present()->email(), + 'phone' => $this->powerboard->client->present()->phone(), + 'type' => 'card', + 'address_line1' => $this->powerboard->client->address1 ?? '', + 'address_line2' => $this->powerboard->client->address2 ?? '', + 'address_state' => $this->powerboard->client->state ?? '', + 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', + 'address_city' => $this->powerboard->client->city ?? '', + 'address_postcode' => $this->powerboard->client->postal_code ?? '', + 'store_ccv' => true, ]; - $this->powerboard->gatewayRequest('/v1/vault/payment_sources', 'post', $payload, []); - // $stripe_response = json_decode($request->input('gateway_response')); + $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, $payload, []); - // $customer = $this->powerboard->findOrCreateCustomer(); + // { + // "status": 201, + // "error": null, + // "resource": { + // "type": "payment_source", + // "data": { + // "type": "card", + // "_source_ip_address": "54.86.50.139", + // "expire_month": 1, + // "expire_year": 2023, + // "card_name": "John Citizen", + // "card_number_last4": "4242", + // "card_number_bin": "42424242", + // "card_scheme": "visa", + // "ref_token": "cus_hyyau7dpojJttR", + // "status": "active", + // "created_at": "2021-08-05T07:04:25.974Z", + // "company_id": "5d305bfbfac31b4448c738d7", + // "vault_token": "c90dbe45-7a23-4f26-9192-336a01e58e59", + // "updated_at": "2021-08-05T07:05:56.035Z" + // } + // } + // } - // $this->stripe->attach($stripe_response->payment_method, $customer); + if($r->successful()){ + + $response_payload = $r->object(); - // $stripe_method = $this->stripe->getStripePaymentMethod($stripe_response->payment_method); + $cgt = $this->storeGatewayToken($request, $response_payload); - // $this->storePaymentMethod($stripe_method, $request->payment_method_id, $customer); + return redirect()->route('client.payment_methods.index'); + + } + + return $this->powerboard->processInternallyFailedPayment($this->powerboard, $r->throw()); - return redirect()->route('client.payment_methods.index'); } + private function storeGatewayToken($request, $response_payload) + { + + try { + + $payment_meta = new \stdClass(); + $payment_meta->exp_month = (string) $response_payload->resource->data->expire_month; + $payment_meta->exp_year = (string) $response_payload->resource->data->expire_year; + $payment_meta->brand = (string) $response_payload->resource->data->card_scheme; + $payment_meta->last4 = (string) $response_payload->resource->data->card_number_last4; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $response_payload->resource->data->vault_token, + 'payment_method_id' => $request->payment_method_id, + ]; + + $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->resource->data->ref_token]); + + } catch (\Exception $e) { + return $this->powerboard->processInternallyFailedPayment($this->powerboard, $e); + } + + } + + public function paymentData(array $data): array { - // $description = $this->stripe->getDescription(false); + $merge = [ 'public_key' => $this->powerboard->company_gateway->getConfigField('publicKey'), 'widget_endpoint' => $this->powerboard->widget_endpoint, @@ -71,7 +135,6 @@ class CreditCard implements LivewireMethodInterface 'environment' => $this->powerboard->environment, ]; - return array_merge($data, $merge); } @@ -193,25 +256,4 @@ class CreditCard implements LivewireMethodInterface // throw new PaymentFailed('Failed to process the payment.', 500); } - private function storePaymentMethod($method, $payment_method_id, $customer) - { - // try { - // $payment_meta = new \stdClass(); - // $payment_meta->exp_month = (string) $method->card->exp_month; - // $payment_meta->exp_year = (string) $method->card->exp_year; - // $payment_meta->brand = (string) $method->card->brand; - // $payment_meta->last4 = (string) $method->card->last4; - // $payment_meta->type = GatewayType::CREDIT_CARD; - - // $data = [ - // 'payment_meta' => $payment_meta, - // 'token' => $method->id, - // 'payment_method_id' => $payment_method_id, - // ]; - - // $this->stripe->storeGatewayToken($data, ['gateway_customer_reference' => $customer->id]); - // } catch (\Exception $e) { - // return $this->stripe->processInternallyFailedPayment($this->stripe, $e); - // } - } } diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index 6e005e6d3bfd..fe2af9488a37 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -22,6 +22,7 @@ use App\Models\PaymentType; use App\Jobs\Util\SystemLogger; use App\Utils\Traits\MakesHash; use App\Models\ClientGatewayToken; +use Illuminate\Support\Facades\Http; use App\PaymentDrivers\CBAPowerBoard\CreditCard; /** @@ -108,7 +109,7 @@ class CBAPowerBoardPaymentDriver extends BaseDriver * @param ClientGatewayToken $token * @return void */ - public function detach(ClientGatewayToken $token) + public function detach(ClientGatewayToken $token): bool { // Driver doesn't support this feature. } diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 35dc0680f9c4..dede88facf53 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -63,6 +63,7 @@
+ @include('portal.ninja2020.gateways.includes.save_card') @include('portal.ninja2020.gateways.includes.pay_now') @endsection @@ -134,11 +135,19 @@ return; } - // // payNow.disabled = true; - // // payNow.querySelector('svg').classList.remove('hidden'); - // // payNow.querySelector('span').classList.add('hidden'); - // - document.getElementById('stub').click(); + payNow.disabled = true; + payNow.querySelector('svg').classList.remove('hidden'); + payNow.querySelector('span').classList.add('hidden'); + + let storeCard = document.querySelector( + 'input[name=token-billing-checkbox]:checked' + ); + + if (storeCard) { + document.getElementById('store_card').value = storeCard.value; + } + + document.getElementById('stub').click(); }); From 67407103c75bf2525f93cba61a810181cdec0586 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 6 Sep 2024 23:14:21 +1000 Subject: [PATCH 07/33] Powerboard --- .../CBAPowerBoard/CreditCard.php | 79 +++++++++++++------ .../CBAPowerBoardPaymentDriver.php | 3 +- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 17c1913041bf..0e8920db322e 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -30,18 +30,20 @@ class CreditCard implements LivewireMethodInterface public function authorizeView(array $data) { - return render('gateways.powerboard.credit_card.authorize', $this->paymentData($data)); } public function authorizeResponse($request) { - $this->powerboard->init(); + $cgt = $this->storePaymentMethod($request); - $payment_source = $request->gateway_response; - - $payload = [ - 'token' => $payment_source, + return redirect()->route('client.payment_methods.index'); + + } + + private function getCustomer(): array + { + return [ 'first_name' => $this->powerboard->client->present()->first_name(), 'last_name' => $this->powerboard->client->present()->first_name(), 'email' => $this->powerboard->client->present()->email(), @@ -53,12 +55,21 @@ class CreditCard implements LivewireMethodInterface 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', 'address_city' => $this->powerboard->client->city ?? '', 'address_postcode' => $this->powerboard->client->postal_code ?? '', + ]; + } + private function storePaymentMethod($request) + { + + $this->powerboard->init(); + + $payment_source = $request->gateway_response; + + $payload = [ + 'token' => $payment_source, 'store_ccv' => true, ]; - - - $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, $payload, []); + $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, array_merge($this->getCustomer(), $payload), []); // { // "status": 201, @@ -84,22 +95,11 @@ class CreditCard implements LivewireMethodInterface // } // } - if($r->successful()){ - - $response_payload = $r->object(); - $cgt = $this->storeGatewayToken($request, $response_payload); + if($r->failed()) + return $this->powerboard->processInternallyFailedPayment($this->powerboard, $r->throw()); - return redirect()->route('client.payment_methods.index'); - - } - - return $this->powerboard->processInternallyFailedPayment($this->powerboard, $r->throw()); - - } - - private function storeGatewayToken($request, $response_payload) - { + $response_payload = $r->object(); try { @@ -116,7 +116,9 @@ class CreditCard implements LivewireMethodInterface 'payment_method_id' => $request->payment_method_id, ]; - $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->resource->data->ref_token]); + $cgt = $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->resource->data->ref_token]); + + return $cgt; } catch (\Exception $e) { return $this->powerboard->processInternallyFailedPayment($this->powerboard, $e); @@ -150,10 +152,39 @@ class CreditCard implements LivewireMethodInterface return 'gateways.powerboard.credit_card.pay_livewire'; } + public function tokenBilling($request, $cgt, $client_present = false) + { + + } + public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); + if($request->store_card) { + $cgt = $this->storePaymentMethod($request); + $this->tokenBilling($request, $cgt, true); + } + + $payload = [ + 'amount' => $this->powerboard->payment_hash->amount_with_fee(), + 'currency' => $this->powerboard->client->currency()->code, + 'description' => $this->powerboard->getDescription(), + // 'descriptor' => , + // 'reference' => , + // 'reference2' => , + // 'amount_surcharge' => , + // 'amount_original' => , + // 'initialization_source' => , + 'bypass_3ds' => false, + // 'token'=> , + 'payment_source_id' => $request->payment_source, + // 'customer_id' => , + 'customer' => $this->getCustomer(), + ]; + + + // $this->stripe->init(); // $state = [ diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index fe2af9488a37..6b514c116364 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -107,11 +107,12 @@ class CBAPowerBoardPaymentDriver extends BaseDriver * Detach payment method from custom payment driver. * * @param ClientGatewayToken $token - * @return void + * @return bool */ public function detach(ClientGatewayToken $token): bool { // Driver doesn't support this feature. + return true; } public function refund(Payment $payment, $amount, $return_client_response = false) From 6d2638c603f75e9a29e8431e61dc6f2cc9b7f3ec Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 09:34:53 +1000 Subject: [PATCH 08/33] powerboard --- app/Enum/HttpVerb.php | 22 ++ .../CBAPowerBoard/CreditCard.php | 15 +- app/PaymentDrivers/CBAPowerBoard/Customer.php | 215 ++++++++++++++++++ .../CBAPowerBoardPaymentDriver.php | 13 ++ .../powerboard/credit_card/pay.blade.php | 68 ++++-- 5 files changed, 312 insertions(+), 21 deletions(-) create mode 100644 app/Enum/HttpVerb.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Customer.php diff --git a/app/Enum/HttpVerb.php b/app/Enum/HttpVerb.php new file mode 100644 index 000000000000..ef7572cacc3a --- /dev/null +++ b/app/Enum/HttpVerb.php @@ -0,0 +1,22 @@ +gateway_response; - $payload = [ + $customer = $this->powerboard->customer()->findOrCreateCustomer($payment_source); + + nlog($customer); + + $payload = array_merge($this->getCustomer(), [ 'token' => $payment_source, 'store_ccv' => true, - ]; + ]); - $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, array_merge($this->getCustomer(), $payload), []); + nlog($payload); + + $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, $payload, []); // { // "status": 201, @@ -116,7 +122,8 @@ class CreditCard implements LivewireMethodInterface 'payment_method_id' => $request->payment_method_id, ]; - $cgt = $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->resource->data->ref_token]); + //['gateway_customer_reference' => $response_payload->resource->data->ref_token] + $cgt = $this->powerboard->storeGatewayToken($data, []); return $cgt; diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php new file mode 100644 index 000000000000..7ad4266f2e0f --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -0,0 +1,215 @@ +powerboard + ->client + ->gateway_tokens() + ->where('company_gateway_id', $this->powerboard->company_gateway->id) + ->first(); + + if($token && $customer = $this->getCustomer($token->gateway_customer_reference)){ + return $customer; + } + + if($customer = $this->findCustomer()) + return $customer; + + return $this->createCustomer(['token' => $payment_source]); + + } + + public function getCustomer(string $id): mixed + { + $uri = "/v1/customers/{$id}"; + + $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::GET)->value, [], []); + + if($r->successful()) + return $r->object(); + + + return false; + } + + public function findCustomer(): mixed + { + $uri = '/v1/customers'; + + $query = [ + 'reference' => $this->powerboard->client->client_hash, + ]; + + $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::GET)->value, $query, []); + + $search_results = $r->object(); + + return reset($search_results->resource->data); // returns first element or false + + } + + /* + token +2 string(UIID) One-time token with all the payment source information + reference - string Manually defined reference for customer in payment systems + description - string Customer description. This is customer internal description + company_name - string Customer company name + first_name - string Customer first name + last_name - string Customer last name + email - string Customer email + phone - string(E.164) Customer phone in E.164 international notation (Example: +12345678901) + default_source + string (24 hex characters) Payment source used by default + payment_source + object Object with payment information + payment_source.gateway_id -4 string (24 hex characters) Gateway id + payment_source.vault_token +3 string (UIID) Vault token + payment_source.type + string Type of payment. card for payment with credit card + payment_source.card_name +1 string Cardholder name (as on card) + payment_source.card_number +1 string(numeric) Card number + payment_source.expire_month +1 string(mm) Card expiration month mm + payment_source.expire_year +1 string(yyyy) Card expiration year + payment_source.card_ccv -1 string(numeric) Card CCV number + payment_source.address_line1 - string Customer Address, line 1 + payment_source.address_line2 - string Customer Address, line 2 + payment_source.address_state - string Customer Address, State + payment_source.address_country - string Customer Address, Country Code + payment_source.address_city - string Customer Address, City + payment_source.address_postcode + */ + public function createCustomer(array $data = []): object + { + + // 'address_line1' => $this->powerboard->client->address1 ?? '', + // 'address_line2' => $this->powerboard->client->address2 ?? '', + // 'address_state' => $this->powerboard->client->state ?? '', + // 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', + // 'address_city' => $this->powerboard->client->city ?? '', + // 'address_postcode' => $this->powerboard->client->postal_code ?? '', + + $payload = [ + 'first_name' => $this->powerboard->client->present()->first_name(), + 'last_name' => $this->powerboard->client->present()->first_name(), + 'email' => $this->powerboard->client->present()->email(), + 'phone' => $this->powerboard->client->present()->phone(), + 'reference' => $this->powerboard->client->client_hash, + ]; + + $payload = array_merge($payload, $data); + + $uri = "/v1/customers"; + + $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); + + if($r->successful()) + $this->storePaymentMethod($r->object()); + + return $r->object() ?? $r->throw(); + + } + + /* + { + "status": 201, + "error": null, + "resource": { + "type": "customer", + "data": { + "statistics": { + "successful_transactions": 0, + "total_collected_amount": 0 + }, + "_check_expire_date": false, + "archived": false, + "_source_ip_address": "130.41.62.108", + "_id": "64b09a3d1e04e51be27f16c5", + "company_id": "63cf32a154a870183bf2398a", + "email": "john@test.com", + "first_name": "John", + "last_name": "Customer", + "phone": "+61111111111", + "reference": "Customer 1", + "default_source": "64b09a341e04e51be27f16c2", + "_service": { + "default_gateway_id": "63cf37b142194166721498e9" + }, + "payment_sources": [ + { + "type": "card", + "_id": "64b09a341e04e51be27f16c2", + "expire_month": 1, + "expire_year": 2039, + "card_name": "John Customer", + "card_scheme": "mastercard", + "card_number_last4": "1118", + "card_number_bin": "51111111", + "ref_token": "9191664642213170", + "status": "active", + "created_at": "2023-07-14T00:43:32.375Z", + "gateway_id": "63cf37b142194166721498e9", + "gateway_type": "MasterCard", + "gateway_name": "CommWeb", + "vault_token": "b944dfb0-35f4-47d6-a306-2b79cebf34f3", + "updated_at": "2023-07-14T00:43:41.169Z" + } + ], + "payment_destinations": [], + "updated_at": "2023-07-14T00:43:41.170Z", + "created_at": "2023-07-14T00:43:41.170Z", + "__v": 0 + } + } + } + */ + private function storePaymentMethod(mixed $customer): ClientGatewayToken + { + + $response_payload = $customer->resource->data; + $source = end($customer->resource->data->payment_sources); + + $payment_meta = new \stdClass(); + $payment_meta->exp_month = (string) $source->expire_month; + $payment_meta->exp_year = (string) $source->expire_year; + $payment_meta->brand = (string) $source->card_scheme; + $payment_meta->last4 = (string) $source->card_number_last4; + $payment_meta->gateway_id = (string) $source->gateway_id; + $payment_meta->type = \App\Models\GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $source->vault_token, + 'payment_method_id' => \App\Models\GatewayType::CREDIT_CARD, + ]; + + $cgt = $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->_id]); + + return $cgt; + + } + + + + // public function updateCustomer(string $id, $data): object + // { + + // } +} + diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index 6b514c116364..11840555f73d 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -24,6 +24,7 @@ use App\Utils\Traits\MakesHash; use App\Models\ClientGatewayToken; use Illuminate\Support\Facades\Http; use App\PaymentDrivers\CBAPowerBoard\CreditCard; +use App\PaymentDrivers\CBAPowerBoard\Customer; /** * Class CBAPowerBoardPaymentDriver. @@ -44,6 +45,8 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public string $environment = 'production_cba'; + public const SYSTEM_LOG_TYPE = SystemLog::TYPE_POWERBOARD; + public static $methods = [ GatewayType::CREDIT_CARD => CreditCard::class, ]; @@ -156,8 +159,14 @@ class CBAPowerBoardPaymentDriver extends BaseDriver public function gatewayRequest(string $uri, string $verb, array $payload, array $headers = []) { + $this->init(); + $r = Http::withHeaders($this->getHeaders($headers)) ->{$verb}($this->api_endpoint.$uri, $payload); + + nlog($r->body()); + + return $r; } public function getHeaders(array $headers = []): array @@ -169,4 +178,8 @@ class CBAPowerBoardPaymentDriver extends BaseDriver $headers); } + public function customer(): Customer + { + return new Customer($this); + } } diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index dede88facf53..34121ae2d83b 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -88,39 +88,73 @@ widget.onFinishInsert('input[name="gateway_response"]', "payment_source"); widget.load(); - widget.on("systemError", function(data) { - console.log("Widget Response", data); + widget.trigger('tab', function (data){ - // document.querySelector( - // 'input[name="gateway_response"]' - // ).value = JSON.stringify(data); + console.log("tab Response", data); + + console.log(widget.isValidForm()); + + let payNow = document.getElementById('pay-now'); + + payNow.disabled = widget.isInvalidForm(); }); + widget.trigger('submit_form',function (data){ + + console.log("submit_form Response", data); + + console.log(widget.isValidForm()); + + let payNow = document.getElementById('pay-now'); + + payNow.disabled = widget.isInvalidForm(); + + }); + + widget.trigger('tab',function (data){ + + console.log("tab Response", data); + + console.log(widget.isValidForm()); + + let payNow = document.getElementById('pay-now'); + + payNow.disabled = widget.isInvalidForm(); + + }); + + widget.on("systemError", function(data) { + console.log("systemError Response", data); + }); + widget.on("validationError", function(data) { - console.log("Widget Response", data); - - // document.querySelector( - // 'input[name="gateway_response"]' - // ).value = JSON.stringify(data); - + console.log("validationError", data); }); widget.on("finish", function(data) { - console.log("Widget Response", data); - - // document.querySelector( - // 'input[name="gateway_response"]' - // ).value = JSON.stringify(data); - + console.log("finish", data); }); widget.on('form_submit', function (data) { + + console.log("form_submit", data); + console.log(data); }); widget.on('submit', function (data) { + + console.log("submit", data); + + console.log(data); + }); + + widget.on('tab', function (data) { + + console.log("tab", data); + console.log(data); }); From 9053e6ac7e188e33b8985e27d43670243d16daaa Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 09:52:35 +1000 Subject: [PATCH 09/33] powerboard --- app/PaymentDrivers/BaseDriver.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 7a9b2bd9afd9..a135802eae7f 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -410,6 +410,7 @@ class BaseDriver extends AbstractPaymentDriver if($invoice && $fee_count == 0){ + nlog("apparently no fee, so injecting here!"); $balance = $invoice->balance; From 78367c1e2d7fae5de4bb92752211ae8de780e1ce Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 16:37:20 +1000 Subject: [PATCH 10/33] Add payment method and attach to customer --- .../CBAPowerBoard/CreditCard.php | 102 ++++++++++++++---- app/PaymentDrivers/CBAPowerBoard/Customer.php | 45 ++++++-- 2 files changed, 119 insertions(+), 28 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index c0cb09d235ca..ab369faefeaf 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -63,18 +63,12 @@ class CreditCard implements LivewireMethodInterface $this->powerboard->init(); $payment_source = $request->gateway_response; - - $customer = $this->powerboard->customer()->findOrCreateCustomer($payment_source); - - nlog($customer); $payload = array_merge($this->getCustomer(), [ 'token' => $payment_source, 'store_ccv' => true, ]); - nlog($payload); - $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, $payload, []); // { @@ -105,8 +99,12 @@ class CreditCard implements LivewireMethodInterface if($r->failed()) return $this->powerboard->processInternallyFailedPayment($this->powerboard, $r->throw()); + nlog("payment source saving"); + $response_payload = $r->object(); + nlog($response_payload); + try { $payment_meta = new \stdClass(); @@ -125,6 +123,42 @@ class CreditCard implements LivewireMethodInterface //['gateway_customer_reference' => $response_payload->resource->data->ref_token] $cgt = $this->powerboard->storeGatewayToken($data, []); + $customer_payload = [ + 'payment_source' => [ + 'vault_token' => $cgt->token, + 'address_line1' => $this->powerboard->client->address1 ?? '', + 'address_line2' => $this->powerboard->client->address1 ?? '', + 'address_state' => $this->powerboard->client->state ?? '', + 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', + 'address_city' => $this->powerboard->client->city ?? '', + 'address_postcode' => $this->powerboard->client->postcode ?? '', + ], + ]; + + foreach ($customer_payload['payment_source'] as $key => $value) { + + if (strlen($value ?? '') == 0) { + unset($customer_payload['payment_source'][$key]); + } + + } + + $customer = $this->powerboard->customer()->findOrCreateCustomer($customer_payload); + + $cgt->gateway_customer_reference = $customer->_id; + $cgt->save(); + + //test that payment token is attached to customer here + + $hit=false; + foreach($customer->payment_sources as $source){ + if($source->vault_token == $cgt->token) + $hit = true; + } + + if(!$hit) + $this->powerboard->customer()->addTokenToCustomer($cgt->token, $customer); + return $cgt; } catch (\Exception $e) { @@ -168,28 +202,52 @@ class CreditCard implements LivewireMethodInterface { nlog($request->all()); + $token = $request->payment_source; + $payload = []; + if($request->store_card) { - $cgt = $this->storePaymentMethod($request); - $this->tokenBilling($request, $cgt, true); + + nlog("Store Payment Method"); + + $customer = $this->storePaymentMethod($request); + + nlog($customer); + + $payload["customer"] = [ + "payment_source" => [ + "vault_token" => "c90dbe45-7a23-4f26-9192-336a01e58e59", + "gateway_id" => "5dde1f3799cfea21ed2fc942" + ] + ]; } + $uri = '/v1/charges'; + $payload = [ - 'amount' => $this->powerboard->payment_hash->amount_with_fee(), - 'currency' => $this->powerboard->client->currency()->code, - 'description' => $this->powerboard->getDescription(), - // 'descriptor' => , - // 'reference' => , - // 'reference2' => , - // 'amount_surcharge' => , - // 'amount_original' => , - // 'initialization_source' => , - 'bypass_3ds' => false, - // 'token'=> , - 'payment_source_id' => $request->payment_source, - // 'customer_id' => , - 'customer' => $this->getCustomer(), + "amount" => "10.00", + "currency" =>"AUD", + ]; + $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); + + // $payload = [ + // 'amount' => $this->powerboard->payment_hash->amount_with_fee(), + // 'currency' => $this->powerboard->client->currency()->code, + // 'description' => $this->powerboard->getDescription(), + // // 'descriptor' => , + // // 'reference' => , + // // 'reference2' => , + // // 'amount_surcharge' => , + // // 'amount_original' => , + // // 'initialization_source' => , + // 'bypass_3ds' => false, + // // 'token'=> , + // 'payment_source_id' => $request->payment_source, + // // 'customer_id' => , + // 'customer' => $this->getCustomer(), + // ]; + // $this->stripe->init(); diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 7ad4266f2e0f..953825c8ebe0 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -21,22 +21,23 @@ class Customer { } - public function findOrCreateCustomer(string $payment_source): mixed + public function findOrCreateCustomer(array $customer_data): mixed { $token = $this->powerboard ->client ->gateway_tokens() + ->whereNotNull('gateway_customer_reference') ->where('company_gateway_id', $this->powerboard->company_gateway->id) ->first(); if($token && $customer = $this->getCustomer($token->gateway_customer_reference)){ - return $customer; + return $customer->resource->data; } if($customer = $this->findCustomer()) return $customer; - return $this->createCustomer(['token' => $payment_source]); + return $this->createCustomer($customer_data); } @@ -65,7 +66,12 @@ class Customer $search_results = $r->object(); - return reset($search_results->resource->data); // returns first element or false + nlog("find customer"); + nlog($search_results); + $customers = $search_results->resource->data; + + nlog($customers); + return reset($customers); // returns first element or false } @@ -97,6 +103,7 @@ class Customer */ public function createCustomer(array $data = []): object { + nlog("creating customer flow"); // 'address_line1' => $this->powerboard->client->address1 ?? '', // 'address_line2' => $this->powerboard->client->address2 ?? '', @@ -109,12 +116,21 @@ class Customer 'first_name' => $this->powerboard->client->present()->first_name(), 'last_name' => $this->powerboard->client->present()->first_name(), 'email' => $this->powerboard->client->present()->email(), - 'phone' => $this->powerboard->client->present()->phone(), 'reference' => $this->powerboard->client->client_hash, + 'phone' => $this->powerboard->client->present()->phone(), ]; + foreach($payload as $key => $value){ + + if(strlen($value ?? '') == 0) + unset($payload[$key]); + + } + $payload = array_merge($payload, $data); + nlog($payload); + $uri = "/v1/customers"; $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); @@ -122,7 +138,7 @@ class Customer if($r->successful()) $this->storePaymentMethod($r->object()); - return $r->object() ?? $r->throw(); + return $r->object()->resource->data ?? $r->throw(); } @@ -206,6 +222,23 @@ class Customer } + public function addTokenToCustomer(string $token, mixed $customer): mixed + { + + $uri = "/v1/customers/{$customer->_id}"; + + $payload = [ + 'payment_source' => [ + 'vault_token' => $token, + ] + ]; + + $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); + + return $r->successful() ? $r->object() : $r->throw(); + } + + // public function updateCustomer(string $id, $data): object // { From c0483d727fb1e5b1027af0d7f47e353a28784765 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 17:27:00 +1000 Subject: [PATCH 11/33] Symfony Serializer --- app/PaymentDrivers/CBAPowerBoard/Customer.php | 4 +- .../CBAPowerBoard/Models/Customer.php | 84 +++++++++++++++++ .../CBAPowerBoard/Models/Parse.php | 70 ++++++++++++++ .../CBAPowerBoard/Models/PaymentSources.php | 92 +++++++++++++++++++ 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Customer.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Parse.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 953825c8ebe0..480fdb5f05e0 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -13,6 +13,7 @@ namespace App\PaymentDrivers\CBAPowerBoard; use App\Models\ClientGatewayToken; +use App\PaymentDrivers\CBAPowerBoard\Models\Customer as ModelsCustomer; use App\PaymentDrivers\CBAPowerBoardPaymentDriver; class Customer @@ -31,7 +32,7 @@ class Customer ->first(); if($token && $customer = $this->getCustomer($token->gateway_customer_reference)){ - return $customer->resource->data; + return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->decode(ModelsCustomer::class, $customer->resource->data); } if($customer = $this->findCustomer()) @@ -113,6 +114,7 @@ class Customer // 'address_postcode' => $this->powerboard->client->postal_code ?? '', $payload = [ + 'company_name' => $this->powerboard->client->present()->name(), 'first_name' => $this->powerboard->client->present()->first_name(), 'last_name' => $this->powerboard->client->present()->first_name(), 'email' => $this->powerboard->client->present()->email(), diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php new file mode 100644 index 000000000000..b04600c658a6 --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php @@ -0,0 +1,84 @@ +_id = $_id; + $this->_source_ip_address = $_source_ip_address; + $this->first_name = $first_name; + $this->last_name = $last_name; + $this->email = $email; + $this->reference = $reference; + $this->default_source = $default_source; + $this->status = $status; + $this->archived = $archived; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->_check_expire_date = $_check_expire_date; + $this->payment_sources = $payment_sources; + $this->payment_destinations = $payment_destinations; + $this->company_id = $company_id; + } +} \ No newline at end of file diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php b/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php new file mode 100644 index 000000000000..b6693c387224 --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php @@ -0,0 +1,70 @@ +deserialize(json_encode($document), $object_type, 'json', [\Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::SKIP_NULL_VALUES => true]); + + return $data; + + } +} \ No newline at end of file diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php new file mode 100644 index 000000000000..8bd4c579218e --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php @@ -0,0 +1,92 @@ +_id = $_id; + $this->type = $type; + $this->vault_token = $vault_token; + $this->card_name = $card_name; + $this->card_number_bin = $card_number_bin; + $this->card_number_last4 = $card_number_last4; + $this->card_scheme = $card_scheme; + $this->address_line1 = $address_line1; + $this->address_line2 = $address_line2; + $this->address_city = $address_city; + $this->address_country = $address_country; + $this->address_state = $address_state; + $this->expire_month = $expire_month; + $this->expire_year = $expire_year; + $this->status = $status; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->vault_type = $vault_type; + } +} From e721351a4b0efac6bcc3578371ff7cb6f3ec7a6f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 17:28:48 +1000 Subject: [PATCH 12/33] Symfony Serializer --- app/PaymentDrivers/CBAPowerBoard/Customer.php | 7 ++++--- app/PaymentDrivers/CBAPowerBoard/Models/Parse.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 480fdb5f05e0..92ac86ab5778 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -32,11 +32,12 @@ class Customer ->first(); if($token && $customer = $this->getCustomer($token->gateway_customer_reference)){ - return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->decode(ModelsCustomer::class, $customer->resource->data); + return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $customer->resource->data); } if($customer = $this->findCustomer()) - return $customer; + return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $customer); + return $this->createCustomer($customer_data); @@ -140,7 +141,7 @@ class Customer if($r->successful()) $this->storePaymentMethod($r->object()); - return $r->object()->resource->data ?? $r->throw(); + return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $r->object()->resource->data) ?? $r->throw(); } diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php b/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php index b6693c387224..55d213a33e3e 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Parse.php @@ -29,7 +29,7 @@ class Parse { } - public function decode($object_type, $document) + public function encode($object_type, $document) { $phpDocExtractor = new PhpDocExtractor(); @@ -61,7 +61,7 @@ class Parse $encoders = [new JsonEncoder()]; $serializer = new Serializer($normalizers, $encoders); -nlog($document); + $data = $serializer->deserialize(json_encode($document), $object_type, 'json', [\Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::SKIP_NULL_VALUES => true]); return $data; From a9aa6aea87b1d493f08d05478c89398b1791bca9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sat, 7 Sep 2024 17:32:23 +1000 Subject: [PATCH 13/33] Customers model: --- app/PaymentDrivers/CBAPowerBoard/Customer.php | 98 +------------------ .../CBAPowerBoard/Models/Customers.php | 18 ++++ 2 files changed, 19 insertions(+), 97 deletions(-) create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Customers.php diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 92ac86ab5778..9078b5d4e58b 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -68,52 +68,15 @@ class Customer $search_results = $r->object(); - nlog("find customer"); - nlog($search_results); $customers = $search_results->resource->data; - nlog($customers); return reset($customers); // returns first element or false } - /* - token +2 string(UIID) One-time token with all the payment source information - reference - string Manually defined reference for customer in payment systems - description - string Customer description. This is customer internal description - company_name - string Customer company name - first_name - string Customer first name - last_name - string Customer last name - email - string Customer email - phone - string(E.164) Customer phone in E.164 international notation (Example: +12345678901) - default_source + string (24 hex characters) Payment source used by default - payment_source + object Object with payment information - payment_source.gateway_id -4 string (24 hex characters) Gateway id - payment_source.vault_token +3 string (UIID) Vault token - payment_source.type + string Type of payment. card for payment with credit card - payment_source.card_name +1 string Cardholder name (as on card) - payment_source.card_number +1 string(numeric) Card number - payment_source.expire_month +1 string(mm) Card expiration month mm - payment_source.expire_year +1 string(yyyy) Card expiration year - payment_source.card_ccv -1 string(numeric) Card CCV number - payment_source.address_line1 - string Customer Address, line 1 - payment_source.address_line2 - string Customer Address, line 2 - payment_source.address_state - string Customer Address, State - payment_source.address_country - string Customer Address, Country Code - payment_source.address_city - string Customer Address, City - payment_source.address_postcode - */ public function createCustomer(array $data = []): object { - nlog("creating customer flow"); - - // 'address_line1' => $this->powerboard->client->address1 ?? '', - // 'address_line2' => $this->powerboard->client->address2 ?? '', - // 'address_state' => $this->powerboard->client->state ?? '', - // 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', - // 'address_city' => $this->powerboard->client->city ?? '', - // 'address_postcode' => $this->powerboard->client->postal_code ?? '', - + $payload = [ 'company_name' => $this->powerboard->client->present()->name(), 'first_name' => $this->powerboard->client->present()->first_name(), @@ -145,59 +108,6 @@ class Customer } - /* - { - "status": 201, - "error": null, - "resource": { - "type": "customer", - "data": { - "statistics": { - "successful_transactions": 0, - "total_collected_amount": 0 - }, - "_check_expire_date": false, - "archived": false, - "_source_ip_address": "130.41.62.108", - "_id": "64b09a3d1e04e51be27f16c5", - "company_id": "63cf32a154a870183bf2398a", - "email": "john@test.com", - "first_name": "John", - "last_name": "Customer", - "phone": "+61111111111", - "reference": "Customer 1", - "default_source": "64b09a341e04e51be27f16c2", - "_service": { - "default_gateway_id": "63cf37b142194166721498e9" - }, - "payment_sources": [ - { - "type": "card", - "_id": "64b09a341e04e51be27f16c2", - "expire_month": 1, - "expire_year": 2039, - "card_name": "John Customer", - "card_scheme": "mastercard", - "card_number_last4": "1118", - "card_number_bin": "51111111", - "ref_token": "9191664642213170", - "status": "active", - "created_at": "2023-07-14T00:43:32.375Z", - "gateway_id": "63cf37b142194166721498e9", - "gateway_type": "MasterCard", - "gateway_name": "CommWeb", - "vault_token": "b944dfb0-35f4-47d6-a306-2b79cebf34f3", - "updated_at": "2023-07-14T00:43:41.169Z" - } - ], - "payment_destinations": [], - "updated_at": "2023-07-14T00:43:41.170Z", - "created_at": "2023-07-14T00:43:41.170Z", - "__v": 0 - } - } - } - */ private function storePaymentMethod(mixed $customer): ClientGatewayToken { @@ -241,11 +151,5 @@ class Customer return $r->successful() ? $r->object() : $r->throw(); } - - - // public function updateCustomer(string $id, $data): object - // { - - // } } diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php new file mode 100644 index 000000000000..ea3c5ac2f27a --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php @@ -0,0 +1,18 @@ + Date: Sun, 8 Sep 2024 19:06:31 +1000 Subject: [PATCH 14/33] powerboard --- app/Helpers/Sanitizer.php | 28 ++ .../CBAPowerBoard/CreditCard.php | 349 ++++++++---------- app/PaymentDrivers/CBAPowerBoard/Customer.php | 95 ++++- .../CBAPowerBoard/Models/Charge.php | 87 +++++ .../CBAPowerBoard/Models/Customer.php | 4 +- .../CBAPowerBoard/Models/PaymentSource.php | 96 +++++ .../CBAPowerBoard/Models/PaymentSources.php | 78 +--- .../CBAPowerBoard/Models/Transaction.php | 64 ++++ .../ninja2020/gateways/paypal/pay.blade.php | 2 +- .../powerboard/credit_card/pay.blade.php | 109 +++++- 10 files changed, 609 insertions(+), 303 deletions(-) create mode 100644 app/Helpers/Sanitizer.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Charge.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php diff --git a/app/Helpers/Sanitizer.php b/app/Helpers/Sanitizer.php new file mode 100644 index 000000000000..2c8598b00859 --- /dev/null +++ b/app/Helpers/Sanitizer.php @@ -0,0 +1,28 @@ + $this->powerboard->client->present()->first_name(), 'last_name' => $this->powerboard->client->present()->first_name(), 'email' => $this->powerboard->client->present()->email(), - 'phone' => $this->powerboard->client->present()->phone(), - 'type' => 'card', + // 'phone' => $this->powerboard->client->present()->phone(), + // 'type' => 'card', 'address_line1' => $this->powerboard->client->address1 ?? '', 'address_line2' => $this->powerboard->client->address2 ?? '', 'address_state' => $this->powerboard->client->state ?? '', @@ -56,8 +59,12 @@ class CreditCard implements LivewireMethodInterface 'address_city' => $this->powerboard->client->city ?? '', 'address_postcode' => $this->powerboard->client->postal_code ?? '', ]; + + return \App\Helpers\Sanitizer::removeBlanks($data); + } - private function storePaymentMethod($request) + + private function storePaymentSource($request) { $this->powerboard->init(); @@ -66,104 +73,24 @@ class CreditCard implements LivewireMethodInterface $payload = array_merge($this->getCustomer(), [ 'token' => $payment_source, + "vault_type" => "session", 'store_ccv' => true, ]); $r = $this->powerboard->gatewayRequest('/v1/vault/payment_sources', (\App\Enum\HttpVerb::POST)->value, $payload, []); - // { - // "status": 201, - // "error": null, - // "resource": { - // "type": "payment_source", - // "data": { - // "type": "card", - // "_source_ip_address": "54.86.50.139", - // "expire_month": 1, - // "expire_year": 2023, - // "card_name": "John Citizen", - // "card_number_last4": "4242", - // "card_number_bin": "42424242", - // "card_scheme": "visa", - // "ref_token": "cus_hyyau7dpojJttR", - // "status": "active", - // "created_at": "2021-08-05T07:04:25.974Z", - // "company_id": "5d305bfbfac31b4448c738d7", - // "vault_token": "c90dbe45-7a23-4f26-9192-336a01e58e59", - // "updated_at": "2021-08-05T07:05:56.035Z" - // } - // } - // } - - if($r->failed()) return $this->powerboard->processInternallyFailedPayment($this->powerboard, $r->throw()); - nlog("payment source saving"); + nlog($r->object()); - $response_payload = $r->object(); + $source = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(PaymentSource ::class, $r->object()->resource->data); - nlog($response_payload); + return $source; - try { + // $cgt = $this->powerboard->customer()->storePaymentMethod(payment_source: $source, store_card: $request->store_card); - $payment_meta = new \stdClass(); - $payment_meta->exp_month = (string) $response_payload->resource->data->expire_month; - $payment_meta->exp_year = (string) $response_payload->resource->data->expire_year; - $payment_meta->brand = (string) $response_payload->resource->data->card_scheme; - $payment_meta->last4 = (string) $response_payload->resource->data->card_number_last4; - $payment_meta->type = GatewayType::CREDIT_CARD; - - $data = [ - 'payment_meta' => $payment_meta, - 'token' => $response_payload->resource->data->vault_token, - 'payment_method_id' => $request->payment_method_id, - ]; - - //['gateway_customer_reference' => $response_payload->resource->data->ref_token] - $cgt = $this->powerboard->storeGatewayToken($data, []); - - $customer_payload = [ - 'payment_source' => [ - 'vault_token' => $cgt->token, - 'address_line1' => $this->powerboard->client->address1 ?? '', - 'address_line2' => $this->powerboard->client->address1 ?? '', - 'address_state' => $this->powerboard->client->state ?? '', - 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', - 'address_city' => $this->powerboard->client->city ?? '', - 'address_postcode' => $this->powerboard->client->postcode ?? '', - ], - ]; - - foreach ($customer_payload['payment_source'] as $key => $value) { - - if (strlen($value ?? '') == 0) { - unset($customer_payload['payment_source'][$key]); - } - - } - - $customer = $this->powerboard->customer()->findOrCreateCustomer($customer_payload); - - $cgt->gateway_customer_reference = $customer->_id; - $cgt->save(); - - //test that payment token is attached to customer here - - $hit=false; - foreach($customer->payment_sources as $source){ - if($source->vault_token == $cgt->token) - $hit = true; - } - - if(!$hit) - $this->powerboard->customer()->addTokenToCustomer($cgt->token, $customer); - - return $cgt; - - } catch (\Exception $e) { - return $this->powerboard->processInternallyFailedPayment($this->powerboard, $e); - } + // return $cgt; } @@ -198,137 +125,171 @@ class CreditCard implements LivewireMethodInterface } + private function get3dsToken(PaymentSource $source, $request) + { + + $payment_hash = PaymentHash::query()->where('hash', $request->payment_hash)->first(); + + $browser_details = json_decode($request->browser_details,true); + + $payload = [ + "amount" => $payment_hash->data->amount_with_fee, + "currency" => $this->powerboard->client->currency()->code, + "description" => $this->powerboard->getDescription(), + "customer" => [ + "payment_source" => [ + "vault_token" => $source->vault_token, + "gateway_id" => '66d65c5a68b7fa297a31c267', + ], + ], + "_3ds" => [ + "browser_details" => $browser_details, + ], + ]; + + nlog($payload); + + $r = $this->powerboard->gatewayRequest('/v1/charges/3ds', (\App\Enum\HttpVerb::POST)->value, $payload, []); + + nlog($r->body()); + + if($r->failed()) + $r->throw(); + + $charge = $r->json(); + nlog($charge['resource']['data']); + return response()->json($charge['resource']['data'], 200); + + } + public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); + $payment_hash = PaymentHash::where('hash', $request->payment_has)->first(); - $token = $request->payment_source; + // $token = $request->payment_source; $payload = []; - if($request->store_card) { - - nlog("Store Payment Method"); - - $customer = $this->storePaymentMethod($request); - - nlog($customer); + /** Token Payment */ + if($request->input('token', false)) + { + $cgt = $this->powerboard + ->client + ->gateway_tokens() + ->where('company_gateway_id', $this->powerboard->company_gateway->id) + ->where('token', $request->token) + ->first(); $payload["customer"] = [ "payment_source" => [ - "vault_token" => "c90dbe45-7a23-4f26-9192-336a01e58e59", - "gateway_id" => "5dde1f3799cfea21ed2fc942" + "vault_token" => $cgt->token, + "gateway_id" => $cgt->meta->gateway_id ] ]; + + } + elseif($request->browser_details) + { + $payment_source = $this->storePaymentSource($request); + + return $this->get3dsToken($payment_source, $request); + + } + elseif($request->charge) { + + $payload = [ + '3ds' => [ + 'id' => $request['charge']['charge_3ds_id'], + ], + "amount"=> $payment_hash->data->amount_with_fee, + "currency"=> $this->powerboard->client->currency()->code, + "store_cvv"=> true, + ]; + + $r = $this->powerboard->gatewayRequest("/v1/charges", (\App\Enum\HttpVerb::POST)->value, $payload, []); + + if($r->failed()) + $r->throw(); + + + + $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); + + if ($charge->status == 'complete') { + $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); + return $this->processSuccessfulPayment($charge); + } + + } - $uri = '/v1/charges'; - - $payload = [ - "amount" => "10.00", - "currency" =>"AUD", - - ]; - - $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); - - // $payload = [ - // 'amount' => $this->powerboard->payment_hash->amount_with_fee(), - // 'currency' => $this->powerboard->client->currency()->code, - // 'description' => $this->powerboard->getDescription(), - // // 'descriptor' => , - // // 'reference' => , - // // 'reference2' => , - // // 'amount_surcharge' => , - // // 'amount_original' => , - // // 'initialization_source' => , - // 'bypass_3ds' => false, - // // 'token'=> , - // 'payment_source_id' => $request->payment_source, - // // 'customer_id' => , - // 'customer' => $this->getCustomer(), - // ]; + nlog($request->all()); - // $this->stripe->init(); - - // $state = [ - // 'server_response' => json_decode($request->gateway_response), - // 'payment_hash' => $request->payment_hash, - // ]; - - // $state = array_merge($state, $request->all()); - // $state['store_card'] = boolval($state['store_card']); - - // if ($request->has('token') && ! is_null($request->token)) { - // $state['store_card'] = false; + // else { + + // $payload["customer"] = [ + // "payment_source" => [ + // "vault_token" => $cgt->token, + // "gateway_id" => $cgt->meta->gateway_id + // ] + // ]; + // } - // $state['payment_intent'] = PaymentIntent::retrieve($state['server_response']->id, array_merge($this->stripe->stripe_connect_auth, ['idempotency_key' => uniqid("st", true)])); - // $state['customer'] = $state['payment_intent']->customer; + // $uri = '/v1/charges'; - // $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, $state); - // $this->stripe->payment_hash->save(); + // $payload_meta = [ + // "amount" => $payment_hash->data->amount_with_fee, + // "currency" => $this->powerboard->client->currency()->code, + // "description" => $this->powerboard->getDescription(), + // ]; - // $server_response = $this->stripe->payment_hash->data->server_response; + // $payload = array_merge($payload, $payload_meta); + + // nlog($payload); - // if ($server_response->status == 'succeeded') { - // $this->stripe->logSuccessfulGatewayResponse(['response' => json_decode($request->gateway_response), 'data' => $this->stripe->payment_hash], SystemLog::TYPE_STRIPE); + // $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); - // return $this->processSuccessfulPayment(); - // } + // if($r->failed()) + // $r->throw(); - // return $this->processUnsuccessfulPayment($server_response); + // nlog($r->object()); + + // return $this->processUnsuccessfulPayment($r->body()); } - public function processSuccessfulPayment() + public function processSuccessfulPayment(Charge $charge) { - // UpdateCustomer::dispatch($this->stripe->company_gateway->company->company_key, $this->stripe->company_gateway->id, $this->stripe->client->id); - // $stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method); + $data = [ + 'payment_type' => PaymentType::CREDIT_CARD_OTHER, + 'amount' => $this->powerboard->payment_hash->data->amount_with_fee, + 'transaction_reference' => $charge->_id, + 'gateway_type_id' => GatewayType::CREDIT_CARD, + ]; - // $data = [ - // 'payment_method' => $this->stripe->payment_hash->data->server_response->payment_method, - // 'payment_type' => PaymentType::parseCardType(strtolower($stripe_method->card->brand)) ?: PaymentType::CREDIT_CARD_OTHER, - // 'amount' => $this->stripe->convertFromStripeAmount($this->stripe->payment_hash->data->server_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()), - // 'transaction_reference' => isset($this->stripe->payment_hash->data->payment_intent->latest_charge) ? $this->stripe->payment_hash->data->payment_intent->latest_charge : optional($this->stripe->payment_hash->data->payment_intent->charges->data[0])->id, - // 'gateway_type_id' => GatewayType::CREDIT_CARD, - // ]; + $payment = $this->powerboard->createPayment($data, Payment::STATUS_COMPLETED); - // $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['amount' => $data['amount']]); - // $this->stripe->payment_hash->save(); + SystemLogger::dispatch( + ['response' => $this->powerboard->payment_hash->data->server_response, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_POWERBOARD, + $this->powerboard->client, + $this->powerboard->client->company, + ); - // if ($this->stripe->payment_hash->data->store_card) { - // $customer = new \stdClass(); - // $customer->id = $this->stripe->payment_hash->data->customer; + if ($payment->invoices()->whereHas('subscription')->exists()) { + $subscription = $payment->invoices()->first()->subscription; - // $this->stripe->attach($this->stripe->payment_hash->data->server_response->payment_method, $customer); + if ($subscription && array_key_exists('return_url', $subscription->webhook_configuration) && strlen($subscription->webhook_configuration['return_url']) >= 1) { + return redirect($subscription->webhook_configuration['return_url']); + } + } - // $stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method); - - // $this->storePaymentMethod($stripe_method, $this->stripe->payment_hash->data->payment_method_id, $customer); - // } - - // $payment = $this->stripe->createPayment($data, Payment::STATUS_COMPLETED); - - // SystemLogger::dispatch( - // ['response' => $this->stripe->payment_hash->data->server_response, 'data' => $data], - // SystemLog::CATEGORY_GATEWAY_RESPONSE, - // SystemLog::EVENT_GATEWAY_SUCCESS, - // SystemLog::TYPE_STRIPE, - // $this->stripe->client, - // $this->stripe->client->company, - // ); - - // if ($payment->invoices()->whereHas('subscription')->exists()) { - // $subscription = $payment->invoices()->first()->subscription; - - // if ($subscription && array_key_exists('return_url', $subscription->webhook_configuration) && strlen($subscription->webhook_configuration['return_url']) >= 1) { - // return redirect($subscription->webhook_configuration['return_url']); - // } - // } - - // return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); + return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); } public function processUnsuccessfulPayment($server_response) diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 9078b5d4e58b..8020401dbdaa 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -12,8 +12,10 @@ namespace App\PaymentDrivers\CBAPowerBoard; +use App\Helpers\Sanitizer; use App\Models\ClientGatewayToken; use App\PaymentDrivers\CBAPowerBoard\Models\Customer as ModelsCustomer; +use App\PaymentDrivers\CBAPowerBoard\Models\PaymentSource; use App\PaymentDrivers\CBAPowerBoardPaymentDriver; class Customer @@ -49,10 +51,11 @@ class Customer $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::GET)->value, [], []); + nlog($r->json()); + if($r->successful()) return $r->object(); - return false; } @@ -68,6 +71,8 @@ class Customer $search_results = $r->object(); + nlog($search_results); + $customers = $search_results->resource->data; return reset($customers); // returns first element or false @@ -83,17 +88,13 @@ class Customer 'last_name' => $this->powerboard->client->present()->first_name(), 'email' => $this->powerboard->client->present()->email(), 'reference' => $this->powerboard->client->client_hash, - 'phone' => $this->powerboard->client->present()->phone(), + // 'phone' => $this->powerboard->client->present()->phone(), ]; - foreach($payload as $key => $value){ - - if(strlen($value ?? '') == 0) - unset($payload[$key]); - - } - + $payload = array_merge($payload, $data); + + $payload = Sanitizer::removeBlanks($payload); nlog($payload); @@ -101,25 +102,29 @@ class Customer $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); - if($r->successful()) - $this->storePaymentMethod($r->object()); + if($r->failed()) + $r->throw(); + + // $this->storePaymentMethod($r->object()); return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $r->object()->resource->data) ?? $r->throw(); } - private function storePaymentMethod(mixed $customer): ClientGatewayToken + public function storePaymentMethod(?PaymentSource $payment_source = null, ?ModelsCustomer $customer = null, bool $store_card = false): ClientGatewayToken { - $response_payload = $customer->resource->data; - $source = end($customer->resource->data->payment_sources); + // $response_payload = $customer->resource->data; + // $source = end($customer->resource->data->payment_sources); + /** @var PaymentSource $source */ + $source = $payment_source ? $payment_source : end($customer->payment_sources); $payment_meta = new \stdClass(); $payment_meta->exp_month = (string) $source->expire_month; $payment_meta->exp_year = (string) $source->expire_year; $payment_meta->brand = (string) $source->card_scheme; $payment_meta->last4 = (string) $source->card_number_last4; - $payment_meta->gateway_id = (string) $source->gateway_id; + $payment_meta->gateway_id = is_null($source->gateway_id) ? (string) $source->gateway_id : false; $payment_meta->type = \App\Models\GatewayType::CREDIT_CARD; $data = [ @@ -128,16 +133,37 @@ class Customer 'payment_method_id' => \App\Models\GatewayType::CREDIT_CARD, ]; - $cgt = $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $response_payload->_id]); + $additional_data = $customer ? ['gateway_customer_reference' => $customer->_id] : []; + $cgt = $this->powerboard->storeGatewayToken($data, $additional_data); - return $cgt; + if($customer || !$store_card) + return $cgt; + + $customer_payload = [ + 'payment_source' => [ + 'vault_token' => $cgt->token, + 'address_line1' => $this->powerboard->client->address1 ?? '', + 'address_line2' => $this->powerboard->client->address1 ?? '', + 'address_state' => $this->powerboard->client->state ?? '', + 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', + 'address_city' => $this->powerboard->client->city ?? '', + 'address_postcode' => $this->powerboard->client->postcode ?? '', + ], + ]; + + $customer = $this->findOrCreateCustomer($customer_payload); + + $this->addTokenToCustomer($cgt->token, $customer); + + return $cgt->fresh(); } - public function addTokenToCustomer(string $token, mixed $customer): mixed + public function addTokenToCustomer(string $token, ModelsCustomer $customer): mixed { - + nlog("add token to customer"); + $uri = "/v1/customers/{$customer->_id}"; $payload = [ @@ -148,7 +174,36 @@ class Customer $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); - return $r->successful() ? $r->object() : $r->throw(); + if($r->failed()){ + nlog($r->body()); + return $r->throw(); + } + + nlog($r->object()); + + $customer = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $r->object()->resource->data); + + $source = collect($customer->payment_sources)->first(function (PaymentSource $source) use ($token){ + return $token == $source->vault_token; + }); + + nlog("i found the source"); + nlog($source); + + $cgt = $this->powerboard + ->client + ->gateway_tokens() + ->where('token', $token) + ->first(); + + nlog($cgt->id); + + $meta = $cgt->meta; + $meta->gateway_id = $source->gateway_id; + $cgt->meta = $meta; + $cgt->save(); + + return $r->object(); } } diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php b/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php new file mode 100644 index 000000000000..3afb255fdc5c --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php @@ -0,0 +1,87 @@ +external_id = $external_id; + $this->_id = $_id; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->remittance_date = $remittance_date; + $this->company_id = $company_id; + $this->amount = $amount; + $this->currency = $currency; + $this->__v = $__v; + $this->transactions = $transactions; + $this->one_off = $one_off; + $this->archived = $archived; + $this->customer = $customer; + $this->capture = $capture; + $this->status = $status; + $this->items = $items; + } +} diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php index b04600c658a6..bcb1da8aefe1 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php @@ -38,7 +38,7 @@ class Customer public string $updated_at; /** @var bool */ public bool $_check_expire_date; - /** @var PaymentSources[] */ + /** @var PaymentSource[] */ public array $payment_sources; /** @var array */ public array $payment_destinations; @@ -46,7 +46,7 @@ class Customer public string $company_id; /** - * @param PaymentSources[] $payment_sources + * @param PaymentSource[] $payment_sources */ public function __construct( string $_id, diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php new file mode 100644 index 000000000000..5d9f27e0fa5b --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php @@ -0,0 +1,96 @@ +_id = $_id; + $this->type = $type; + $this->vault_token = $vault_token; + $this->card_name = $card_name; + $this->card_number_bin = $card_number_bin; + $this->card_number_last4 = $card_number_last4; + $this->card_scheme = $card_scheme; + $this->address_line1 = $address_line1; + $this->address_line2 = $address_line2; + $this->address_city = $address_city; + $this->address_country = $address_country; + $this->address_state = $address_state; + $this->expire_month = $expire_month; + $this->expire_year = $expire_year; + $this->status = $status; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->vault_type = $vault_type; + $this->gateway_id = $gateway_id; + } +} diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php index 8bd4c579218e..0698e6f4078a 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSources.php @@ -13,80 +13,6 @@ namespace App\PaymentDrivers\CBAPowerBoard\Models; class PaymentSources { - /** @var string */ - public string $_id; - /** @var string */ - public string $type; - /** @var string */ - public string $vault_token; - /** @var string */ - public string $card_name; - /** @var string */ - public string $card_number_bin; - /** @var string */ - public string $card_number_last4; - /** @var string */ - public string $card_scheme; - /** @var string|null */ - public ?string $address_line1; - /** @var string|null */ - public ?string $address_line2; - /** @var string|null */ - public ?string $address_city; - /** @var string|null */ - public ?string $address_country; - /** @var string|null */ - public ?string $address_state; - /** @var int */ - public int $expire_month; - /** @var int */ - public int $expire_year; - /** @var string */ - public string $status; - /** @var string */ - public string $created_at; - /** @var string */ - public string $updated_at; - /** @var string */ - public string $vault_type; - - public function __construct( - string $_id, - string $type, - string $vault_token, - string $card_name, - string $card_number_bin, - string $card_number_last4, - string $card_scheme, - ?string $address_line1, - ?string $address_line2, - ?string $address_city, - ?string $address_country, - ?string $address_state, - int $expire_month, - int $expire_year, - string $status, - string $created_at, - string $updated_at, - string $vault_type - ) { - $this->_id = $_id; - $this->type = $type; - $this->vault_token = $vault_token; - $this->card_name = $card_name; - $this->card_number_bin = $card_number_bin; - $this->card_number_last4 = $card_number_last4; - $this->card_scheme = $card_scheme; - $this->address_line1 = $address_line1; - $this->address_line2 = $address_line2; - $this->address_city = $address_city; - $this->address_country = $address_country; - $this->address_state = $address_state; - $this->expire_month = $expire_month; - $this->expire_year = $expire_year; - $this->status = $status; - $this->created_at = $created_at; - $this->updated_at = $updated_at; - $this->vault_type = $vault_type; - } + /** @var \App\PaymentDrivers\CBAPowerBoard\Models\PaymentSources[] */ + public array $payment_sources; } diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php b/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php new file mode 100644 index 000000000000..33c7c07fca48 --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php @@ -0,0 +1,64 @@ +created_at = $created_at; + $this->amount = $amount; + $this->currency = $currency; + $this->_id = $_id; + $this->error_code = $error_code; + $this->error_message = $error_message; + $this->gateway_specific_description = $gateway_specific_description; + $this->gateway_specific_code = $gateway_specific_code; + $this->_source_ip_address = $_source_ip_address; + $this->status = $status; + $this->type = $type; + } +} diff --git a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php index b6c83d9149e9..cac76ec1a7ce 100644 --- a/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/paypal/pay.blade.php @@ -93,7 +93,7 @@ inset: 6px; document.getElementById("gateway_response").value =JSON.stringify( data ); formData = JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server_response")))), - + fetch('{{ route('client.payments.response') }}', { method: 'POST', headers: { diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 34121ae2d83b..1fca07754e6d 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -16,6 +16,8 @@ + + @@ -63,6 +65,7 @@
+ @include('portal.ninja2020.gateways.includes.save_card') @include('portal.ninja2020.gateways.includes.pay_now') @@ -84,7 +87,7 @@ var widget = new cba.HtmlWidget('#widget', '{{ $public_key }}', 'not_configured'); widget.setEnv("{{ $environment }}"); widget.useAutoResize(); - widget.interceptSubmitForm('#server-response'); + // widget.interceptSubmitForm('#server-response'); widget.onFinishInsert('input[name="gateway_response"]', "payment_source"); widget.load(); @@ -131,30 +134,69 @@ widget.on("validationError", function(data) { console.log("validationError", data); }); + + widget.on("finish", async function(data) { - - widget.on("finish", function(data) { console.log("finish", data); + + try { + const resource = await get3dsToken(); + console.log("3DS Token:", resource); + + console.log("pre canvas"); + + var canvas = new cba.Canvas3ds('#widget-3dsecure', resource._3ds.token); + canvas.load(); + + console.log("post canvas"); + + canvas.on("chargeAuthSuccess", function(data) { + console.log(data); + + document.querySelector( + 'input[name="browser_details"]' + ).value = null; + + document.querySelector( + 'input[name="charge"]' + ).value = JSON.stringify(data); + + + document.getElementById('server-response').submit(); + + }); + + canvas.on("chargeAuthReject", function(data) { + console.log(data); + }); + + } catch (error) { + console.error("Error fetching 3DS Token:", error); + } + }); - widget.on('form_submit', function (data) { - - console.log("form_submit", data); + widget.on("submit", async function (data){ + console.log("submit"); + console.log(data); + + + + }) + + widget.on('form_submit', function (data) { + console.log("form_submit", data); console.log(data); }); widget.on('submit', function (data) { - console.log("submit", data); - console.log(data); }); widget.on('tab', function (data) { - console.log("tab", data); - console.log(data); }); @@ -185,6 +227,53 @@ }); + + async function get3dsToken() { + + const browserDetails = { + name: navigator.userAgent.substring(0, 100), // The full user agent string, which contains the browser name and version + java_enabled: navigator.javaEnabled() ? "true" : "false", // Indicates if Java is enabled in the browser + language: navigator.language || navigator.userLanguage, // The browser language + screen_height: window.screen.height.toString(), // Screen height in pixels + screen_width: window.screen.width.toString(), // Screen width in pixels + time_zone: (new Date().getTimezoneOffset() * -1).toString(), // Timezone offset in minutes (negative for behind UTC) + color_depth: window.screen.colorDepth.toString() // Color depth in bits per pixel + }; + + document.querySelector( + 'input[name="browser_details"]' + ).value = JSON.stringify(browserDetails); + + const formData = JSON.stringify(Object.fromEntries(new FormData(document.getElementById("server-response")))); + + try { + // Return the fetch promise to handle it externally + const response = await fetch('{{ route('client.payments.response') }}', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + "X-Requested-With": "XMLHttpRequest", + "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content + }, + body: formData + }) + + + if (!response.ok) { + const text = await response.text(); + throw new Error(`Network response was not ok: ${response.statusText}. Response text: ${text}`); + } + + return await response.json() + + } + catch(error) { + + console.error('Fetch error:', error); // Log error for debugging + throw error; // + + } + } @endsection From 590616a7805af42b3826ca83b44c1da302882d33 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Sun, 8 Sep 2024 19:52:39 +1000 Subject: [PATCH 15/33] Payment with 3ds --- .../CBAPowerBoard/CreditCard.php | 16 ++- .../CBAPowerBoard/Models/Charge.php | 89 +++++++------- .../CBAPowerBoard/Models/Customer.php | 93 +++++++------- .../CBAPowerBoard/Models/Transaction.php | 113 ++++++++++-------- .../powerboard/credit_card/pay.blade.php | 58 ++++----- 5 files changed, 193 insertions(+), 176 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 85e6a7875cbf..c9c37eb70c62 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -165,7 +165,7 @@ class CreditCard implements LivewireMethodInterface public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); - $payment_hash = PaymentHash::where('hash', $request->payment_has)->first(); + $payment_hash = PaymentHash::where('hash', $request->payment_hash)->first(); // $token = $request->payment_source; $payload = []; @@ -197,22 +197,26 @@ class CreditCard implements LivewireMethodInterface } elseif($request->charge) { + $charge_request = json_decode($request->charge, true); + + nlog($charge_request); + $payload = [ - '3ds' => [ - 'id' => $request['charge']['charge_3ds_id'], + '_3ds' => [ + 'id' => $charge_request['charge_3ds_id'], ], "amount"=> $payment_hash->data->amount_with_fee, "currency"=> $this->powerboard->client->currency()->code, "store_cvv"=> true, ]; + nlog($payload); + $r = $this->powerboard->gatewayRequest("/v1/charges", (\App\Enum\HttpVerb::POST)->value, $payload, []); if($r->failed()) $r->throw(); - - $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); if ($charge->status == 'complete') { @@ -273,7 +277,7 @@ class CreditCard implements LivewireMethodInterface $payment = $this->powerboard->createPayment($data, Payment::STATUS_COMPLETED); SystemLogger::dispatch( - ['response' => $this->powerboard->payment_hash->data->server_response, 'data' => $data], + ['response' => $charge, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_POWERBOARD, diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php b/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php index 3afb255fdc5c..a165876c0608 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Charge.php @@ -13,59 +13,56 @@ namespace App\PaymentDrivers\CBAPowerBoard\Models; class Charge { - /** @var string */ - public string $external_id; - /** @var string */ - public string $_id; - /** @var string */ - public string $created_at; - /** @var string */ - public string $updated_at; - /** @var string */ - public string $remittance_date; - /** @var string */ - public string $company_id; - /** @var int */ - public int $amount; - /** @var string */ - public string $currency; - /** @var int */ - public int $__v; - /** @var Transactions[] */ + /** @var ?string */ + public ?string $external_id; + /** @var ?string */ + public ?string $_id; + /** @var ?string */ + public ?string $created_at; + /** @var ?string */ + public ?string $updated_at; + /** @var ?string */ + public ?string $remittance_date; + /** @var ?string */ + public ?string $company_id; + /** @var float */ + public float $amount; + /** @var ?string */ + public ?string $currency; + /** @var ?int */ + public ?int $__v; + /** @var Transaction[] */ public array $transactions; - /** @var bool */ - public bool $one_off; - /** @var bool */ - public bool $archived; + /** @var ?bool */ + public ?bool $one_off; + /** @var ?bool */ + public ?bool $archived; /** @var Customer */ public Customer $customer; - /** @var bool */ - public bool $capture; - /** @var string */ - public string $status; - /** @var array */ - public array $items; + /** @var ?bool */ + public ?bool $capture; + /** @var ?string */ + public? string $status; + /** @var ?array */ + public ?array $items; - /** - * @param Transactions[] $transactions - */ public function __construct( - string $external_id, - string $_id, - string $created_at, - string $updated_at, - string $remittance_date, - string $company_id, - int $amount, - string $currency, - int $__v, + ?string $external_id, + ?string $_id, + ?string $created_at, + ?string $updated_at, + ?string $remittance_date, + ?string $company_id, + float $amount, + ?string $currency, + ?int $__v, array $transactions, - bool $one_off, - bool $archived, + ?bool $one_off, + ?bool $archived, Customer $customer, - bool $capture, - string $status, - array $items, + ?bool $capture, + ?string $status, + ?array $items, ) { $this->external_id = $external_id; $this->_id = $_id; diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php index bcb1da8aefe1..b6b52ded3948 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php @@ -14,56 +14,53 @@ namespace App\PaymentDrivers\CBAPowerBoard\Models; class Customer { - /** @var string */ - public string $_id; - /** @var string */ - public string $_source_ip_address; - /** @var string */ - public string $first_name; - /** @var string */ - public string $last_name; - /** @var string */ - public string $email; - /** @var string */ - public string $reference; - /** @var string */ - public string $default_source; - /** @var string */ - public string $status; - /** @var bool */ - public bool $archived; - /** @var string */ - public string $created_at; - /** @var string */ - public string $updated_at; - /** @var bool */ - public bool $_check_expire_date; - /** @var PaymentSource[] */ - public array $payment_sources; - /** @var array */ - public array $payment_destinations; - /** @var string */ - public string $company_id; + /** @var ?string */ + public ?string $_id; + /** @var ?string */ + public ?string $_source_ip_address; + /** @var ?string */ + public ?string $first_name; + /** @var ?string */ + public ?string $last_name; + /** @var ?string */ + public ?string $email; + /** @var ?string */ + public ?string $reference; + /** @var ?string */ + public ?string $default_source; + /** @var ?string */ + public ?string $status; + /** @var ?bool */ + public ?bool $archived; + /** @var ?string */ + public ?string $created_at; + /** @var ?string */ + public ?string $updated_at; + /** @var ?bool */ + public ?bool $_check_expire_date; + /** @var ?PaymentSource[] */ + public ?array $payment_sources; + /** @var ?array */ + public ?array $payment_destinations; + /** @var ?string */ + public ?string $company_id; - /** - * @param PaymentSource[] $payment_sources - */ public function __construct( - string $_id, - string $_source_ip_address, - string $first_name, - string $last_name, - string $email, - string $reference, - string $default_source, - string $status, - bool $archived, - string $created_at, - string $updated_at, - bool $_check_expire_date, - array $payment_sources, - array $payment_destinations, - string $company_id + ?string $_id, + ?string $_source_ip_address, + ?string $first_name, + ?string $last_name, + ?string $email, + ?string $reference, + ?string $default_source, + ?string $status, + ?bool $archived, + ?string $created_at, + ?string $updated_at, + ?bool $_check_expire_date, + ?array $payment_sources, + ?array $payment_destinations, + ?string $company_id ) { $this->_id = $_id; $this->_source_ip_address = $_source_ip_address; diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php b/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php index 33c7c07fca48..7ed6fef8bc55 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php @@ -11,54 +11,69 @@ namespace App\PaymentDrivers\CBAPowerBoard\Models; -class Transactions +class Threeds { - /** @var string */ - public string $created_at; - /** @var int */ - public int $amount; - /** @var string */ - public string $currency; - /** @var string */ - public string $_id; - /** @var string */ - public ?string $error_code; - /** @var ?string */ - public ?string $error_message; - /** @var ?string */ - public ?string $gateway_specific_description; - /** @var ?string */ - public ?string $gateway_specific_code; - /** @var string */ - public string $_source_ip_address; - /** @var string */ - public string $status; - /** @var string */ - public string $type; - - public function __construct( - string $created_at, - int $amount, - string $currency, - string $_id, - ?string $error_code, - ?string $error_message, - ?string $gateway_specific_description, - ?string $gateway_specific_code, - string $_source_ip_address, - string $status, - string $type - ) { - $this->created_at = $created_at; - $this->amount = $amount; - $this->currency = $currency; - $this->_id = $_id; - $this->error_code = $error_code; - $this->error_message = $error_message; - $this->gateway_specific_description = $gateway_specific_description; - $this->gateway_specific_code = $gateway_specific_code; - $this->_source_ip_address = $_source_ip_address; - $this->status = $status; - $this->type = $type; - } + public function __construct(public ?string $token){} +} + +class Transaction +{ + public ?Threeds $_3ds; + public ?string $gateway_specific_code; + public ?string $gateway_specific_description; + public ?string $error_message; + public ?string $error_code; + public ?string $status_code; + public ?string $status_code_description; + public ?string $type; + public ?string $status; + public float $amount; + public ?string $currency; + public ?string $_id; + public ?string $created_at; + public ?string $updated_at; + public ?string $processed_at; + public ?string $external_id; + public ?string $external_reference; + public ?string $authorization_code; + + public function __construct( + ?Threeds $_3ds, + ?string $gateway_specific_code, + ?string $gateway_specific_description, + ?string $error_message, + ?string $error_code, + ?string $status_code, + ?string $status_code_description, + ?string $type, + ?string $status, + float $amount, + ?string $currency, + ?string $_id, + ?string $created_at, + ?string $updated_at, + ?string $processed_at, + ?string $external_id, + ?string $external_reference, + ?string $authorization_code + ) { + $this->_3ds = $_3ds; + $this->gateway_specific_code = $gateway_specific_code; + $this->gateway_specific_description = $gateway_specific_description; + $this->error_message = $error_message; + $this->error_code = $error_code; + $this->status_code = $status_code; + $this->status_code_description = $status_code_description; + $this->type = $type; + $this->status = $status; + $this->amount = $amount; + $this->currency = $currency; + $this->_id = $_id; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->processed_at = $processed_at; + $this->external_id = $external_id; + $this->external_reference = $external_reference; + $this->authorization_code = $authorization_code; + } } diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 1fca07754e6d..9f1cd1fdfb97 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -64,6 +64,7 @@
+
@include('portal.ninja2020.gateways.includes.save_card') @@ -144,45 +145,48 @@ console.log("3DS Token:", resource); console.log("pre canvas"); - + console.log(resource._3ds.token); + var canvas = new cba.Canvas3ds('#widget-3dsecure', resource._3ds.token); canvas.load(); - - console.log("post canvas"); - - canvas.on("chargeAuthSuccess", function(data) { - console.log(data); + + let widget = document.getElementById('widget'); + widget.classList.add('hidden'); - document.querySelector( - 'input[name="browser_details"]' - ).value = null; - - document.querySelector( - 'input[name="charge"]' - ).value = JSON.stringify(data); - - - document.getElementById('server-response').submit(); - - }); - - canvas.on("chargeAuthReject", function(data) { - console.log(data); - }); } catch (error) { console.error("Error fetching 3DS Token:", error); } + + + canvas.on("chargeAuthSuccess", function(data) { + console.log(data); + + document.querySelector( + 'input[name="browser_details"]' + ).value = null; + + document.querySelector( + 'input[name="charge"]' + ).value = JSON.stringify(data); + + document.getElementById('server-response').submit(); + + }); + + canvas.on("chargeAuthReject", function(data) { + console.log(data); + }); + + + canvas.load(); + }); widget.on("submit", async function (data){ console.log("submit"); - console.log(data); - - - - + console.log(data); }) widget.on('form_submit', function (data) { From 2e114692e7268a6d8aa54a71c0775061ef246d47 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 15:52:11 +1000 Subject: [PATCH 16/33] 3ds payment flow --- .../CBAPowerBoard/CreditCard.php | 65 ++++++++----------- app/PaymentDrivers/CBAPowerBoard/Customer.php | 2 - .../CBAPowerBoard/Models/Customer.php | 6 +- .../CBAPowerBoard/Models/PaymentSource.php | 24 +++---- .../powerboard/credit_card/pay.blade.php | 8 +++ 5 files changed, 51 insertions(+), 54 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index c9c37eb70c62..b28b3b3bd2a7 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -73,7 +73,7 @@ class CreditCard implements LivewireMethodInterface $payload = array_merge($this->getCustomer(), [ 'token' => $payment_source, - "vault_type" => "session", + "vault_type" => "permanent", 'store_ccv' => true, ]); @@ -165,7 +165,9 @@ class CreditCard implements LivewireMethodInterface public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); - $payment_hash = PaymentHash::where('hash', $request->payment_hash)->first(); + $this->powerboard->payment_hash->data = array_merge((array) $this->powerboard->payment_hash->data, ['response' => $request->all()]); + $this->powerboard->payment_hash->save(); + // $token = $request->payment_source; $payload = []; @@ -192,20 +194,22 @@ class CreditCard implements LivewireMethodInterface { $payment_source = $this->storePaymentSource($request); + nlog($payment_source); + return $this->get3dsToken($payment_source, $request); } elseif($request->charge) { $charge_request = json_decode($request->charge, true); - + nlog("we have the charge request"); nlog($charge_request); $payload = [ '_3ds' => [ 'id' => $charge_request['charge_3ds_id'], ], - "amount"=> $payment_hash->data->amount_with_fee, + "amount"=> $this->powerboard->payment_hash->data->amount_with_fee, "currency"=> $this->powerboard->client->currency()->code, "store_cvv"=> true, ]; @@ -219,49 +223,32 @@ class CreditCard implements LivewireMethodInterface $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); + nlog($charge); + if ($charge->status == 'complete') { $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); + + $vt = $charge->customer->payment_source->vault_token; + // nlog($this->powerboard->payment_hash->data); + + // $vt = $r->object()->resource->data->_3ds->id; + + if($request->store_card){ + $data = [ + "payment_source" => [ + "vault_token" => $vt, + ], + ]; + + $customer = $this->powerboard->customer()->findOrCreateCustomer($data); + } + return $this->processSuccessfulPayment($charge); } } - - - nlog($request->all()); - - // else { - - // $payload["customer"] = [ - // "payment_source" => [ - // "vault_token" => $cgt->token, - // "gateway_id" => $cgt->meta->gateway_id - // ] - // ]; - - // } - - // $uri = '/v1/charges'; - - // $payload_meta = [ - // "amount" => $payment_hash->data->amount_with_fee, - // "currency" => $this->powerboard->client->currency()->code, - // "description" => $this->powerboard->getDescription(), - // ]; - - // $payload = array_merge($payload, $payload_meta); - - // nlog($payload); - - // $r = $this->powerboard->gatewayRequest($uri, (\App\Enum\HttpVerb::POST)->value, $payload, []); - - // if($r->failed()) - // $r->throw(); - - // nlog($r->object()); - - // return $this->processUnsuccessfulPayment($r->body()); } public function processSuccessfulPayment(Charge $charge) diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 8020401dbdaa..9062f122d1ef 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -105,8 +105,6 @@ class Customer if($r->failed()) $r->throw(); - // $this->storePaymentMethod($r->object()); - return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(ModelsCustomer::class, $r->object()->resource->data) ?? $r->throw(); } diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php index b6b52ded3948..a207b79ec719 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/Customer.php @@ -40,6 +40,8 @@ class Customer public ?bool $_check_expire_date; /** @var ?PaymentSource[] */ public ?array $payment_sources; + /** @var ?PaymentSource */ + public ?PaymentSource $payment_source; /** @var ?array */ public ?array $payment_destinations; /** @var ?string */ @@ -60,7 +62,8 @@ class Customer ?bool $_check_expire_date, ?array $payment_sources, ?array $payment_destinations, - ?string $company_id + ?string $company_id, + ?PaymentSource $payment_source ) { $this->_id = $_id; $this->_source_ip_address = $_source_ip_address; @@ -77,5 +80,6 @@ class Customer $this->payment_sources = $payment_sources; $this->payment_destinations = $payment_destinations; $this->company_id = $company_id; + $this->payment_source = $payment_source; } } \ No newline at end of file diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php index 5d9f27e0fa5b..019b2fcfa9d0 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php +++ b/app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php @@ -41,14 +41,14 @@ class PaymentSource public int $expire_month; /** @var int */ public int $expire_year; - /** @var string */ - public string $status; - /** @var string */ - public string $created_at; - /** @var string */ - public string $updated_at; - /** @var string */ - public string $vault_type; + /** @var ?string */ + public ?string $status; + /** @var ?string */ + public ?string $created_at; + /** @var ?string */ + public ?string $updated_at; + /** @var ?string */ + public ?string $vault_type; /** @var ?string */ public ?string $gateway_id; @@ -67,10 +67,10 @@ class PaymentSource ?string $address_state, int $expire_month, int $expire_year, - string $status, - string $created_at, - string $updated_at, - string $vault_type, + ?string $status, + ?string $created_at, + ?string $updated_at, + ?string $vault_type, ?string $gateway_id ) { $this->_id = $_id; diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 9f1cd1fdfb97..b0efe090491e 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -171,6 +171,14 @@ 'input[name="charge"]' ).value = JSON.stringify(data); + let storeCard = document.querySelector( + 'input[name=token-billing-checkbox]:checked' + ); + + if (storeCard) { + document.getElementById('store_card').value = storeCard.value; + } + document.getElementById('server-response').submit(); }); From 54afae4d8bef3545c7f16903c7ca22bb6763fe48 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 16:28:56 +1000 Subject: [PATCH 17/33] Exception handling --- .../CBAPowerBoard/CreditCard.php | 25 +++++++++++++------ .../2024_09_06_042040_cba_powerboard.php | 2 ++ database/seeders/PaymentLibrariesSeeder.php | 2 +- .../powerboard/credit_card/pay.blade.php | 13 +++++++--- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index b28b3b3bd2a7..f26652dc76ab 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -153,8 +153,9 @@ class CreditCard implements LivewireMethodInterface nlog($r->body()); - if($r->failed()) - $r->throw(); + if ($r->failed()) { + return $this->processUnsuccessfulPayment($r); + } $charge = $r->json(); nlog($charge['resource']['data']); @@ -165,6 +166,8 @@ class CreditCard implements LivewireMethodInterface public function paymentResponse(PaymentResponseRequest $request) { nlog($request->all()); + + $request->headers->set('Accept', 'application/json'); $this->powerboard->payment_hash->data = array_merge((array) $this->powerboard->payment_hash->data, ['response' => $request->all()]); $this->powerboard->payment_hash->save(); @@ -219,7 +222,7 @@ class CreditCard implements LivewireMethodInterface $r = $this->powerboard->gatewayRequest("/v1/charges", (\App\Enum\HttpVerb::POST)->value, $payload, []); if($r->failed()) - $r->throw(); + return $this->processUnsuccessfulPayment($r); $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); @@ -229,9 +232,6 @@ class CreditCard implements LivewireMethodInterface $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); $vt = $charge->customer->payment_source->vault_token; - // nlog($this->powerboard->payment_hash->data); - - // $vt = $r->object()->resource->data->_3ds->id; if($request->store_card){ $data = [ @@ -283,8 +283,19 @@ class CreditCard implements LivewireMethodInterface return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); } - public function processUnsuccessfulPayment($server_response) + public function processUnsuccessfulPayment($response) { + try{ + $response->throw(); + } + catch(\Throwable $exception){ + $error_object = $exception->response->object(); + + nlog($error_object); + return response()->json(['message' => $error_object->error->details->messages[0]->gateway_specific_code, 'code' => 400], 400); + } + + // $this->stripe->sendFailureMail($server_response->cancellation_reason); // $message = [ diff --git a/database/migrations/2024_09_06_042040_cba_powerboard.php b/database/migrations/2024_09_06_042040_cba_powerboard.php index d4e756672546..bfeba4de60e1 100644 --- a/database/migrations/2024_09_06_042040_cba_powerboard.php +++ b/database/migrations/2024_09_06_042040_cba_powerboard.php @@ -22,7 +22,9 @@ return new class extends Migration $fields->secretKey = ''; // $fields->applicationId = ''; // $fields->locationId = ''; + $fields->testMode = false; + $fields->Threeds = false; $powerboard = new Gateway(); $powerboard->id = 64; diff --git a/database/seeders/PaymentLibrariesSeeder.php b/database/seeders/PaymentLibrariesSeeder.php index f77761e5acb7..879b65dc8831 100644 --- a/database/seeders/PaymentLibrariesSeeder.php +++ b/database/seeders/PaymentLibrariesSeeder.php @@ -89,7 +89,7 @@ class PaymentLibrariesSeeder extends Seeder ['id' => 61, 'name' => 'PayPal Platform', 'provider' => 'PayPal_PPCP', 'key' => '80af24a6a691230bbec33e930ab40666', 'fields' => '{"testMode":false}'], ['id' => 62, 'name' => 'BTCPay', 'provider' => 'BTCPay', 'key' => 'vpyfbmdrkqcicpkjqdusgjfluebftuva', 'fields' => '{"btcpayUrl":"", "apiKey":"", "storeId":"", "webhookSecret":""}'], ['id' => 63, 'name' => 'Rotessa', 'is_offsite' => false, 'sort_order' => 22, 'provider' => 'Rotessa', 'key' => '91be24c7b792230bced33e930ac61676', 'fields' => '{"apiKey":"", "testMode":false}'], - ['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"publicKey":"", "secretKey":"", "testMode":false}'], + ['id' => 64, 'name' => 'CBA PowerBoard', 'is_offsite' => false, 'sort_order' => 26, 'provider' => 'CBAPowerBoard', 'key' => 'b67581d804dbad1743b61c57285142ad', 'fields' => '{"publicKey":"", "secretKey":"", "testMode":false, "Threeds":true}'], ]; foreach ($gateways as $gateway) { diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index b0efe090491e..67aed5950259 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -265,16 +265,21 @@ headers: { 'Content-Type': 'application/json', "X-Requested-With": "XMLHttpRequest", + "Accept": 'application/json', "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content }, body: formData }) + if (!response.ok) { - if (!response.ok) { - const text = await response.text(); - throw new Error(`Network response was not ok: ${response.statusText}. Response text: ${text}`); - } + return await response.json().then(errorData => { + throw new Error(errorData.message ?? 'Unknown error.'); + }); + + // const text = await response.text(); + // throw new Error(`Network response was not ok: ${response.statusText}. Response text: ${text}`); + } return await response.json() From 0e070ed5c1bb5e9d33c1dcbc586bd5f1c8e4a36f Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 18:19:29 +1000 Subject: [PATCH 18/33] powerboard 3ds flow completion --- .../CBAPowerBoard/CreditCard.php | 4 ++- app/PaymentDrivers/CBAPowerBoard/Customer.php | 30 +++---------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index f26652dc76ab..2315b56a0130 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -231,6 +231,7 @@ class CreditCard implements LivewireMethodInterface if ($charge->status == 'complete') { $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); + $vt = $charge->customer->payment_source->vault_token; if($request->store_card){ @@ -239,8 +240,9 @@ class CreditCard implements LivewireMethodInterface "vault_token" => $vt, ], ]; - + $customer = $this->powerboard->customer()->findOrCreateCustomer($data); + $cgt = $this->powerboard->customer()->storePaymentMethod($charge->customer->payment_source, $charge->customer); } return $this->processSuccessfulPayment($charge); diff --git a/app/PaymentDrivers/CBAPowerBoard/Customer.php b/app/PaymentDrivers/CBAPowerBoard/Customer.php index 9062f122d1ef..9ac9e75da6c1 100644 --- a/app/PaymentDrivers/CBAPowerBoard/Customer.php +++ b/app/PaymentDrivers/CBAPowerBoard/Customer.php @@ -109,11 +109,9 @@ class Customer } - public function storePaymentMethod(?PaymentSource $payment_source = null, ?ModelsCustomer $customer = null, bool $store_card = false): ClientGatewayToken + public function storePaymentMethod(?PaymentSource $payment_source = null, ?ModelsCustomer $customer = null): ClientGatewayToken { - // $response_payload = $customer->resource->data; - // $source = end($customer->resource->data->payment_sources); /** @var PaymentSource $source */ $source = $payment_source ? $payment_source : end($customer->payment_sources); @@ -122,7 +120,7 @@ class Customer $payment_meta->exp_year = (string) $source->expire_year; $payment_meta->brand = (string) $source->card_scheme; $payment_meta->last4 = (string) $source->card_number_last4; - $payment_meta->gateway_id = is_null($source->gateway_id) ? (string) $source->gateway_id : false; + $payment_meta->gateway_id = $source->gateway_id ?? null; $payment_meta->type = \App\Models\GatewayType::CREDIT_CARD; $data = [ @@ -131,30 +129,10 @@ class Customer 'payment_method_id' => \App\Models\GatewayType::CREDIT_CARD, ]; - $additional_data = $customer ? ['gateway_customer_reference' => $customer->_id] : []; - $cgt = $this->powerboard->storeGatewayToken($data, $additional_data); + $cgt = $this->powerboard->storeGatewayToken($data, ['gateway_customer_reference' => $source->gateway_id]); - if($customer || !$store_card) - return $cgt; + return $cgt; - $customer_payload = [ - 'payment_source' => [ - 'vault_token' => $cgt->token, - 'address_line1' => $this->powerboard->client->address1 ?? '', - 'address_line2' => $this->powerboard->client->address1 ?? '', - 'address_state' => $this->powerboard->client->state ?? '', - 'address_country' => $this->powerboard->client->country->iso_3166_3 ?? '', - 'address_city' => $this->powerboard->client->city ?? '', - 'address_postcode' => $this->powerboard->client->postcode ?? '', - ], - ]; - - $customer = $this->findOrCreateCustomer($customer_payload); - - $this->addTokenToCustomer($cgt->token, $customer); - - return $cgt->fresh(); - } From 36899316243541e48d8f4543d0e93a4d2e3471cc Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 18:50:07 +1000 Subject: [PATCH 19/33] powerboard --- .../CBAPowerBoard/CreditCard.php | 39 +++++++++---- .../powerboard/credit_card/pay.blade.php | 58 ++++++++++++++++--- 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 2315b56a0130..c14be334fc6e 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -19,6 +19,7 @@ use App\Models\PaymentHash; use App\Models\PaymentType; use App\Jobs\Util\SystemLogger; use App\Exceptions\PaymentFailed; +use Illuminate\Http\Client\RequestException; use App\PaymentDrivers\CBAPowerBoardPaymentDriver; use App\PaymentDrivers\CBAPowerBoard\Models\Charge; use App\PaymentDrivers\Common\LivewireMethodInterface; @@ -123,6 +124,31 @@ class CreditCard implements LivewireMethodInterface public function tokenBilling($request, $cgt, $client_present = false) { + $payload = [ + "amount" => $this->powerboard->payment_hash->data->amount_with_fee, + "currency" => $this->powerboard->client->currency()->code, + "customer" => [ + "payment_source" => [ + "vault_token" => $cgt->token, + "gateway_id" => $cgt->gateway_customer_reference + ] + ] + ]; + + $r = $this->powerboard->gatewayRequest('/v1/charges', (\App\Enum\HttpVerb::POST)->value, $payload, []); + + nlog($r->body()); + + if($r->failed()); + return $this->processUnsuccessfulPayment($r); + + $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); + + nlog($charge); + + $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); + + return $this->processSuccessfulPayment($charge); } private function get3dsToken(PaymentSource $source, $request) @@ -167,11 +193,9 @@ class CreditCard implements LivewireMethodInterface { nlog($request->all()); - $request->headers->set('Accept', 'application/json'); $this->powerboard->payment_hash->data = array_merge((array) $this->powerboard->payment_hash->data, ['response' => $request->all()]); $this->powerboard->payment_hash->save(); - // $token = $request->payment_source; $payload = []; @@ -185,13 +209,8 @@ class CreditCard implements LivewireMethodInterface ->where('token', $request->token) ->first(); - $payload["customer"] = [ - "payment_source" => [ - "vault_token" => $cgt->token, - "gateway_id" => $cgt->meta->gateway_id - ] - ]; - + return $this->tokenBilling($request, $cgt, true); + } elseif($request->browser_details) { @@ -290,7 +309,7 @@ class CreditCard implements LivewireMethodInterface try{ $response->throw(); } - catch(\Throwable $exception){ + catch(RequestException $exception){ $error_object = $exception->response->object(); nlog($error_object); diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 67aed5950259..054e93e3167d 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -63,7 +63,7 @@ @endcomponent
-
+
@@ -137,6 +137,7 @@ }); widget.on("finish", async function(data) { + document.getElementById('errors').hidden = true; console.log("finish", data); @@ -185,8 +186,11 @@ canvas.on("chargeAuthReject", function(data) { console.log(data); - }); + document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...`; + document.getElementById('errors').hidden = false; + + }); canvas.load(); @@ -195,6 +199,7 @@ widget.on("submit", async function (data){ console.log("submit"); console.log(data); + document.getElementById('errors').hidden = true; }) widget.on('form_submit', function (data) { @@ -216,12 +221,12 @@ payNow.addEventListener('click', () => { - widget.getValidationState(); + // widget.getValidationState(); - if(!widget.isValidForm()){ - console.log("invalid"); - return; - } + // if(!widget.isValidForm()){ + // console.log("invalid"); + // return; + // } payNow.disabled = true; payNow.querySelector('svg').classList.remove('hidden'); @@ -235,7 +240,7 @@ document.getElementById('store_card').value = storeCard.value; } - document.getElementById('stub').click(); + document.getElementById('server-response').submit(); }); @@ -286,11 +291,48 @@ } catch(error) { + document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error.message}`; + document.getElementById('errors').hidden = false; + console.error('Fetch error:', error); // Log error for debugging throw error; // } } + + const first = document.querySelector('input[name="payment-type"]'); + + if (first) { + first.click(); + } + + + document + .getElementById('toggle-payment-with-credit-card') + .addEventListener('click', (element) => { + + let widget = document.getElementById('widget'); + widget.classList.remove('hidden'); + document.getElementById('save-card--container').style.display ='grid'; + document.querySelector('input[name=token]').value = ''; + + }); + + + Array.from( + document.getElementsByClassName('toggle-payment-with-token') + ).forEach((element) => + element.addEventListener('click', (element) => { + document + .getElementById('widget') + .classList.add('hidden'); + document.getElementById( + 'save-card--container' + ).style.display = 'none'; + document.querySelector('input[name=token]').value = + element.target.dataset.token; + }) + ); @endsection From d2d807dd7dcab4056015da0f34e56904c2cb0f4e Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 19:02:25 +1000 Subject: [PATCH 20/33] Powerboard --- app/PaymentDrivers/CBAPowerBoard/CreditCard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index c14be334fc6e..2266c5f97465 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -139,7 +139,7 @@ class CreditCard implements LivewireMethodInterface nlog($r->body()); - if($r->failed()); + if($r->failed()) return $this->processUnsuccessfulPayment($r); $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); From 1172e4bfc19e87fcbc0b3bebae01498f40101654 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 19:36:25 +1000 Subject: [PATCH 21/33] Authorize.blade.php --- app/PaymentDrivers/CBAPowerBoard/CreditCard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 2266c5f97465..1b4c24284d99 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -39,7 +39,7 @@ class CreditCard implements LivewireMethodInterface public function authorizeResponse($request) { - $cgt = $this->storePaymentMethod($request); + $cgt = $this->powerboard->customer()->storePaymentMethod($request); return redirect()->route('client.payment_methods.index'); From 6177483791f18b56e543258615b140368f9d5317 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 9 Sep 2024 19:56:47 +1000 Subject: [PATCH 22/33] Authorize --- .../CBAPowerBoard/CreditCard.php | 97 ++++++- .../CBAPowerBoardPaymentDriver.php | 24 ++ .../credit_card/authorize.blade.php | 246 ++++++++++++++++++ 3 files changed, 361 insertions(+), 6 deletions(-) create mode 100644 resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 1b4c24284d99..5ba8cab91516 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -34,12 +34,101 @@ class CreditCard implements LivewireMethodInterface public function authorizeView(array $data) { + $data['payment_method_id'] = GatewayType::CREDIT_CARD; + return render('gateways.powerboard.credit_card.authorize', $this->paymentData($data)); } public function authorizeResponse($request) { - $cgt = $this->powerboard->customer()->storePaymentMethod($request); + + if($request->browser_details) + { + $payment_source = $this->storePaymentSource($request); + + nlog($payment_source); + + $browser_details = json_decode($request->browser_details, true); + + $payload = [ + "amount" => 1, + "currency" => $this->powerboard->client->currency()->code, + "description" => "Card authorization", + "customer" => [ + "payment_source" => [ + "vault_token" => $payment_source->vault_token, + "gateway_id" => $payment_source->gateway_id, + ], + ], + "_3ds" => [ + "browser_details" => $browser_details, + ], + ]; + + nlog($payload); + + $r = $this->powerboard->gatewayRequest('/v1/charges/3ds', (\App\Enum\HttpVerb::POST)->value, $payload, []); + + if ($r->failed()) { + return $this->processUnsuccessfulPayment($r); + } + + $charge = $r->json(); + nlog($charge['resource']['data']); + return response()->json($charge['resource']['data'], 200); + + + } + elseif($request->charge) { + + $charge_request = json_decode($request->charge, true); + nlog("we have the charge request"); + nlog($charge_request); + + $payload = [ + '_3ds' => [ + 'id' => $charge_request['charge_3ds_id'], + ], + "capture" => false, + "amount"=> 1, + "currency"=> $this->powerboard->client->currency()->code, + "store_cvv"=> true, + ]; + + nlog($payload); + + $r = $this->powerboard->gatewayRequest("/v1/charges", (\App\Enum\HttpVerb::POST)->value, $payload, []); + + if($r->failed()) + return $this->processUnsuccessfulPayment($r); + + $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); + + nlog($charge); + + if ($charge->status == 'complete') { + $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); + + $vt = $charge->customer->payment_source->vault_token; + + if($request->store_card){ + $data = [ + "payment_source" => [ + "vault_token" => $vt, + ], + ]; + + $customer = $this->powerboard->customer()->findOrCreateCustomer($data); + $cgt = $this->powerboard->customer()->storePaymentMethod($charge->customer->payment_source, $charge->customer); + } + + return redirect()->route('client.payment_methods.index'); + } + + + } + + // $cgt = $this->powerboard->customer()->storePaymentMethod($request); return redirect()->route('client.payment_methods.index'); @@ -89,10 +178,6 @@ class CreditCard implements LivewireMethodInterface return $source; - // $cgt = $this->powerboard->customer()->storePaymentMethod(payment_source: $source, store_card: $request->store_card); - - // return $cgt; - } @@ -165,7 +250,7 @@ class CreditCard implements LivewireMethodInterface "customer" => [ "payment_source" => [ "vault_token" => $source->vault_token, - "gateway_id" => '66d65c5a68b7fa297a31c267', + "gateway_id" => $source->gateway_id, ], ], "_3ds" => [ diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index 11840555f73d..ae301b650330 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -83,6 +83,30 @@ class CBAPowerBoardPaymentDriver extends BaseDriver return $this; } + /** + * Proxy method to pass the data into payment method authorizeView(). + * + * @param array $data + * @return \Illuminate\Http\RedirectResponse|mixed + */ + public function authorizeView(array $data) + { + $this->init(); + + return $this->payment_method->authorizeView($data); + } + + /** + * Processes the gateway response for credit card authorization. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\RedirectResponse|mixed + */ + public function authorizeResponse($request) + { + return $this->payment_method->authorizeResponse($request); + } + /** * View for displaying custom content of the driver. * diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php new file mode 100644 index 000000000000..3d78eb6d9345 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php @@ -0,0 +1,246 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Credit card', 'card_title' => 'Credit card']) + +@section('gateway_head') + +@endsection + +@section('gateway_content') + +
+ @csrf + + + + + + +
+ + + + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')]) +
+
+
+
+ @endcomponent + + @component('portal.ninja2020.gateways.includes.pay_now', ['id' => 'authorize-card']) + {{ ctrans('texts.add_payment_method') }} + @endcomponent + +@endsection + +@section('gateway_footer') + + + + + + + +@endsection + + + From b715c7dd204e6a71a5065df1dcf36f879fa20a31 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 10 Sep 2024 08:40:40 +1000 Subject: [PATCH 23/33] powerboardOM --- app/Models/CompanyGateway.php | 14 +++ .../CBAPowerBoard/CreditCard.php | 75 ++++++++++----- .../CBAPowerBoard/Models/Customers.php | 18 ---- .../CBAPowerBoard/Models/Gateway.php | 56 +++++++++++ app/PaymentDrivers/CBAPowerBoard/Settings.php | 96 +++++++++++++++++++ .../CBAPowerBoardPaymentDriver.php | 8 +- .../2024_09_06_042040_cba_powerboard.php | 7 +- .../credit_card/authorize.blade.php | 4 +- .../powerboard/credit_card/pay.blade.php | 2 +- 9 files changed, 232 insertions(+), 48 deletions(-) delete mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Customers.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Models/Gateway.php create mode 100644 app/PaymentDrivers/CBAPowerBoard/Settings.php diff --git a/app/Models/CompanyGateway.php b/app/Models/CompanyGateway.php index f8ff6118490f..73dbae6617d7 100644 --- a/app/Models/CompanyGateway.php +++ b/app/Models/CompanyGateway.php @@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property bool $update_details * @property bool $is_deleted * @property string $config + * @property object $settings * @property mixed $fees_and_limits * @property string|null $custom_value1 * @property string|null $custom_value2 @@ -74,6 +75,7 @@ class CompanyGateway extends BaseModel protected $casts = [ 'fees_and_limits' => 'object', + 'settings' => 'object', 'updated_at' => 'timestamp', 'created_at' => 'timestamp', 'deleted_at' => 'timestamp', @@ -484,6 +486,18 @@ class CompanyGateway extends BaseModel return $fee; } + public function getSettings() + { + // return $this->settings; + return $this->settings ?? new \stdClass; + } + + public function setSettings($settings) + { + $this->settings = $settings; + $this->save(); + } + public function webhookUrl() { return route('payment_webhook', ['company_key' => $this->company->company_key, 'company_gateway_id' => $this->hashed_id]); diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index 5ba8cab91516..87e2577ff8b5 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -25,11 +25,15 @@ use App\PaymentDrivers\CBAPowerBoard\Models\Charge; use App\PaymentDrivers\Common\LivewireMethodInterface; use App\PaymentDrivers\CBAPowerBoard\Models\PaymentSource; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use App\PaymentDrivers\CBAPowerBoard\Models\Gateway; class CreditCard implements LivewireMethodInterface { + private Gateway $cba_gateway; + public function __construct(public CBAPowerBoardPaymentDriver $powerboard) { + $this->cba_gateway = $this->powerboard->settings()->getPaymentGatewayConfiguration(GatewayType::CREDIT_CARD); } public function authorizeView(array $data) @@ -51,13 +55,14 @@ class CreditCard implements LivewireMethodInterface $browser_details = json_decode($request->browser_details, true); $payload = [ + "capture" => false, "amount" => 1, "currency" => $this->powerboard->client->currency()->code, "description" => "Card authorization", "customer" => [ "payment_source" => [ "vault_token" => $payment_source->vault_token, - "gateway_id" => $payment_source->gateway_id, + "gateway_id" => $this->powerboard->settings()->getGatewayId(GatewayType::CREDIT_CARD), ], ], "_3ds" => [ @@ -75,8 +80,8 @@ class CreditCard implements LivewireMethodInterface $charge = $r->json(); nlog($charge['resource']['data']); - return response()->json($charge['resource']['data'], 200); + return response()->json($charge['resource']['data'], 200); } elseif($request->charge) { @@ -90,6 +95,7 @@ class CreditCard implements LivewireMethodInterface 'id' => $charge_request['charge_3ds_id'], ], "capture" => false, + "authorization" => true, "amount"=> 1, "currency"=> $this->powerboard->client->currency()->code, "store_cvv"=> true, @@ -99,30 +105,33 @@ class CreditCard implements LivewireMethodInterface $r = $this->powerboard->gatewayRequest("/v1/charges", (\App\Enum\HttpVerb::POST)->value, $payload, []); - if($r->failed()) - return $this->processUnsuccessfulPayment($r); + if($r->failed()){ + + $error_payload = $this->getErrorFromResponse($r); + throw new PaymentFailed($error_payload[0], $error_payload[1]); + + } $charge = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Charge::class, $r->object()->resource->data) ?? $r->throw(); nlog($charge); if ($charge->status == 'complete') { + $this->powerboard->logSuccessfulGatewayResponse(['response' => $charge, 'data' => $this->powerboard->payment_hash], SystemLog::TYPE_POWERBOARD); $vt = $charge->customer->payment_source->vault_token; - if($request->store_card){ - $data = [ - "payment_source" => [ - "vault_token" => $vt, - ], - ]; - - $customer = $this->powerboard->customer()->findOrCreateCustomer($data); - $cgt = $this->powerboard->customer()->storePaymentMethod($charge->customer->payment_source, $charge->customer); - } + $data = [ + "payment_source" => [ + "vault_token" => $vt, + ], + ]; + + $customer = $this->powerboard->customer()->findOrCreateCustomer($data); + $cgt = $this->powerboard->customer()->storePaymentMethod($charge->customer->payment_source, $charge->customer); - return redirect()->route('client.payment_methods.index'); + return redirect()->route('client.payment_methods.show', ['payment_method' => $cgt->hashed_id]); } @@ -183,12 +192,15 @@ class CreditCard implements LivewireMethodInterface public function paymentData(array $data): array { - + if($this->cba_gateway->verification_status != "completed") + throw new PaymentFailed("This payment method is not configured as yet. Reference Powerboard portal for further information", 400); + $merge = [ 'public_key' => $this->powerboard->company_gateway->getConfigField('publicKey'), 'widget_endpoint' => $this->powerboard->widget_endpoint, 'gateway' => $this->powerboard, 'environment' => $this->powerboard->environment, + 'gateway_id' => $this->cba_gateway->_id, ]; return array_merge($data, $merge); @@ -250,7 +262,7 @@ class CreditCard implements LivewireMethodInterface "customer" => [ "payment_source" => [ "vault_token" => $source->vault_token, - "gateway_id" => $source->gateway_id, + "gateway_id" => $this->powerboard->settings()->getGatewayId(GatewayType::CREDIT_CARD), ], ], "_3ds" => [ @@ -389,18 +401,37 @@ class CreditCard implements LivewireMethodInterface return redirect()->route('client.payments.show', ['payment' => $payment->hashed_id]); } - public function processUnsuccessfulPayment($response) + private function getErrorFromResponse($response) { - try{ + + try { $response->throw(); - } - catch(RequestException $exception){ + } catch (RequestException $exception) { $error_object = $exception->response->object(); + //todo log this error_object nlog($error_object); - return response()->json(['message' => $error_object->error->details->messages[0]->gateway_specific_code, 'code' => 400], 400); + $error_message = "Unknown error"; + + match($error_object->error->code) { + "UnfulfilledCondition" => $error_message = $error_object->error->message, + "transaction_declined" => $error_message = $error_object->error->details[0]->status_code_description, + default => $error_message = "Unknown error", + }; + + return [$error_message, $exception->getCode()]; + } + } + public function processUnsuccessfulPayment($response) + { + + $error_payload = $this->getErrorFromResponse($response); + + return response()->json(['message' => $error_payload[0], 'code' => $error_payload[1]], $error_payload[1]); + + // $this->stripe->sendFailureMail($server_response->cancellation_reason); diff --git a/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php b/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php deleted file mode 100644 index ea3c5ac2f27a..000000000000 --- a/app/PaymentDrivers/CBAPowerBoard/Models/Customers.php +++ /dev/null @@ -1,18 +0,0 @@ -_id = $_id; + $this->name = $name; + $this->type = $type; + $this->mode = $mode; + $this->created_at = $created_at; + $this->updated_at = $updated_at; + $this->archived = $archived; + $this->default = $default; + $this->verification_status = $verification_status; + } +} diff --git a/app/PaymentDrivers/CBAPowerBoard/Settings.php b/app/PaymentDrivers/CBAPowerBoard/Settings.php new file mode 100644 index 000000000000..945a72f48ea7 --- /dev/null +++ b/app/PaymentDrivers/CBAPowerBoard/Settings.php @@ -0,0 +1,96 @@ +powerboard->gatewayRequest('/v1/gateways', (\App\Enum\HttpVerb::GET)->value, [], []); + + if($r->failed()) + $r->throw(); + + nlog($r->object()); + + return (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Gateway::class."[]", $r->object()->resource->data); + + } + + /** We will need to have a process that updates this at intervals */ + public function updateSettings():self + { + $gateways = $this->getGateways(); + + $settings = $this->powerboard->company_gateway->getSettings(); + $settings->gateways = $gateways; + $this->powerboard->company_gateway->setSettings($settings); + + return $this; + } + + public function getSettings(): mixed + { + return $this->powerboard->company_gateway->getSettings(); + } + + public function getPaymentGatewayConfiguration(int $gateway_type_id): mixed + { + $type = self::GATEWAY_CBA; + + match($gateway_type_id){ + \App\Models\GatewayType::CREDIT_CARD => $type = self::GATEWAY_CBA, + default => $type = self::GATEWAY_CBA, + }; + + return $this->getGatewayByType($type); + } + + private function getGatewayByType(string $gateway_type_const): mixed + { + $settings = $this->getSettings(); + + if(!property_exists($settings,'gateways')){ + $this->updateSettings(); + $settings = $this->getSettings(); + } + + $gateways = (new \App\PaymentDrivers\CBAPowerBoard\Models\Parse())->encode(Gateway::class."[]", $settings->gateways); + + return collect($gateways)->first(function (Gateway $gateway) use ($gateway_type_const){ + return $gateway->type == $gateway_type_const; + }); + } + + public function getGatewayId(int $gateway_type_id): string + { + $gateway = $this->getPaymentGatewayConfiguration($gateway_type_id); + + return $gateway->_id; + } +} diff --git a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php index ae301b650330..5e0b64f0af5e 100644 --- a/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php +++ b/app/PaymentDrivers/CBAPowerBoardPaymentDriver.php @@ -25,6 +25,7 @@ use App\Models\ClientGatewayToken; use Illuminate\Support\Facades\Http; use App\PaymentDrivers\CBAPowerBoard\CreditCard; use App\PaymentDrivers\CBAPowerBoard\Customer; +use App\PaymentDrivers\CBAPowerBoard\Settings; /** * Class CBAPowerBoardPaymentDriver. @@ -206,4 +207,9 @@ class CBAPowerBoardPaymentDriver extends BaseDriver { return new Customer($this); } -} + + public function settings(): Settings + { + return new Settings($this); + } +} \ No newline at end of file diff --git a/database/migrations/2024_09_06_042040_cba_powerboard.php b/database/migrations/2024_09_06_042040_cba_powerboard.php index bfeba4de60e1..bcccbb2d2dfd 100644 --- a/database/migrations/2024_09_06_042040_cba_powerboard.php +++ b/database/migrations/2024_09_06_042040_cba_powerboard.php @@ -20,9 +20,6 @@ return new class extends Migration $fields->publicKey = ''; $fields->secretKey = ''; - // $fields->applicationId = ''; - // $fields->locationId = ''; - $fields->testMode = false; $fields->Threeds = false; @@ -37,6 +34,10 @@ return new class extends Migration $powerboard->fields = json_encode($fields); $powerboard->save(); + + Schema::table("company_gateways", function (\Illuminate\Database\Schema\Blueprint $table){ + $table->text('settings')->nullable(); + }); } /** diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php index 3d78eb6d9345..e13ccff69d71 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/authorize.blade.php @@ -18,12 +18,10 @@ - @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.method')])
- @endcomponent @component('portal.ninja2020.gateways.includes.pay_now', ['id' => 'authorize-card']) {{ ctrans('texts.add_payment_method') }} @@ -44,7 +42,7 @@ + + + +@endsection + + + From 53e295df4cb16aa24b0ea3d36ec6b9b3cc9bbdf8 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 10 Sep 2024 11:50:15 +1000 Subject: [PATCH 25/33] Refactor for self hosted pay now button --- .../powerboard/credit_card/pay.blade.php | 187 ++++++++++-------- 1 file changed, 102 insertions(+), 85 deletions(-) diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 0a4ed9e20d8f..d7b0bd06209c 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -6,6 +6,11 @@ @section('gateway_content') +
+ + +
+
@csrf @@ -58,9 +63,7 @@ - - - @endcomponent + @endcomponent
@@ -88,45 +91,45 @@ var widget = new cba.HtmlWidget('#widget', '{{ $public_key }}', '{{ $gateway_id }}'); widget.setEnv("{{ $environment }}"); widget.useAutoResize(); - // widget.interceptSubmitForm('#server-response'); - widget.onFinishInsert('input[name="gateway_response"]', "payment_source"); + widget.interceptSubmitForm('#stepone'); + widget.onFinishInsert('#server-response input[name="gateway_response"]', "payment_source"); widget.load(); - widget.trigger('tab', function (data){ + // widget.trigger('tab', function (data){ - console.log("tab Response", data); + // console.log("tab Response", data); - console.log(widget.isValidForm()); + // console.log(widget.isValidForm()); - let payNow = document.getElementById('pay-now'); + // let payNow = document.getElementById('pay-now'); - payNow.disabled = widget.isInvalidForm(); + // payNow.disabled = widget.isInvalidForm(); - }); + // }); - widget.trigger('submit_form',function (data){ + // widget.trigger('submit_form',function (data){ - console.log("submit_form Response", data); + // console.log("submit_form Response", data); - console.log(widget.isValidForm()); + // console.log(widget.isValidForm()); - let payNow = document.getElementById('pay-now'); + // let payNow = document.getElementById('pay-now'); - payNow.disabled = widget.isInvalidForm(); + // payNow.disabled = widget.isInvalidForm(); - }); + // }); - widget.trigger('tab',function (data){ + // widget.trigger('tab',function (data){ - console.log("tab Response", data); + // console.log("tab Response", data); - console.log(widget.isValidForm()); + // console.log(widget.isValidForm()); - let payNow = document.getElementById('pay-now'); + // let payNow = document.getElementById('pay-now'); - payNow.disabled = widget.isInvalidForm(); + // payNow.disabled = widget.isInvalidForm(); - }); + // }); widget.on("systemError", function(data) { console.log("systemError Response", data); @@ -139,64 +142,14 @@ widget.on("finish", async function(data) { document.getElementById('errors').hidden = true; - console.log("finish", data); - - try { - const resource = await get3dsToken(); - console.log("3DS Token:", resource); - - console.log("pre canvas"); - console.log(resource._3ds.token); - - var canvas = new cba.Canvas3ds('#widget-3dsecure', resource._3ds.token); - canvas.load(); + console.log("finish"); + console.log(data); - let widget = document.getElementById('widget'); - widget.classList.add('hidden'); - - - } catch (error) { - console.error("Error fetching 3DS Token:", error); - } - - - - canvas.on("chargeAuthSuccess", function(data) { - console.log(data); - - document.querySelector( - 'input[name="browser_details"]' - ).value = null; - - document.querySelector( - 'input[name="charge"]' - ).value = JSON.stringify(data); - - let storeCard = document.querySelector( - 'input[name=token-billing-checkbox]:checked' - ); - - if (storeCard) { - document.getElementById('store_card').value = storeCard.value; - } - - document.getElementById('server-response').submit(); - - }); - - canvas.on("chargeAuthReject", function(data) { - console.log(data); - - document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...`; - document.getElementById('errors').hidden = false; - - }); - - canvas.load(); + process3ds(); }); - widget.on("submit", async function (data){ + widget.on("submit", function (data){ console.log("submit"); console.log(data); document.getElementById('errors').hidden = true; @@ -207,11 +160,6 @@ console.log(data); }); - widget.on('submit', function (data) { - console.log("submit", data); - console.log(data); - }); - widget.on('tab', function (data) { console.log("tab", data); console.log(data); @@ -221,7 +169,7 @@ payNow.addEventListener('click', () => { - // widget.getValidationState(); + widget.getValidationState(); // if(!widget.isValidForm()){ // console.log("invalid"); @@ -240,11 +188,81 @@ document.getElementById('store_card').value = storeCard.value; } - document.getElementById('server-response').submit(); + if(document.querySelector('#server-response input[name=gateway_response]').value.length > 1) + document.getElementById('stepone_submit').click(); + else + document.getElementById('server-response').submit(); }); + async function process3ds() + { + + + try { + const resource = await get3dsToken(); + console.log("3DS Token:", resource); + + if(resource.status != 'pre-authenticated') + throw new Error('There was an issue authenticating this payment method.'); + + console.log("pre canvas"); + console.log(resource._3ds.token); + + var canvas = new cba.Canvas3ds('#widget-3dsecure', resource._3ds.token); + canvas.load(); + + let widget = document.getElementById('widget'); + widget.classList.add('hidden'); + + + } catch (error) { + console.error("Error fetching 3DS Token:", error); + + document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...\n\n${error}`; + document.getElementById('errors').hidden = false; + + } + + canvas.on("chargeAuthSuccess", function(data) { + console.log(data); + + document.querySelector( + 'input[name="browser_details"]' + ).value = null; + + document.querySelector( + 'input[name="charge"]' + ).value = JSON.stringify(data); + + let storeCard = document.querySelector( + 'input[name=token-billing-checkbox]:checked' + ); + + if (storeCard) { + document.getElementById('store_card').value = storeCard.value; + } + + document.getElementById('server-response').submit(); + + }); + + canvas.on("chargeAuthReject", function(data) { + console.log(data); + + document.getElementById('errors').textContent = `Sorry, your transaction could not be processed...`; + document.getElementById('errors').hidden = false; + + }); + + canvas.load(); + + + + } + + async function get3dsToken() { const browserDetails = { @@ -318,7 +336,6 @@ }); - Array.from( document.getElementsByClassName('toggle-payment-with-token') ).forEach((element) => From 0c8e5b2e379dd4ea7c2195161264cc2147be05ed Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 10 Sep 2024 12:07:50 +1000 Subject: [PATCH 26/33] Pay Now using ninja tokens --- .../powerboard/credit_card/pay.blade.php | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index d7b0bd06209c..7183b9561afd 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -7,8 +7,8 @@ @section('gateway_content') - - + +
@@ -145,7 +145,13 @@ console.log("finish"); console.log(data); - process3ds(); + + const div = document.getElementById('widget'); + + if(div.offsetParent !== null) + process3ds(); + else + processNon3ds(); }); @@ -188,13 +194,16 @@ document.getElementById('store_card').value = storeCard.value; } - if(document.querySelector('#server-response input[name=gateway_response]').value.length > 1) - document.getElementById('stepone_submit').click(); - else - document.getElementById('server-response').submit(); - + document.getElementById('stepone_submit').click(); + }); + function processNon3ds() + { + + document.getElementById('#server-response').submit(); + + } async function process3ds() { @@ -204,7 +213,7 @@ const resource = await get3dsToken(); console.log("3DS Token:", resource); - if(resource.status != 'pre-authenticated') + if(resource.status != "pre_authentication_pending") throw new Error('There was an issue authenticating this payment method.'); console.log("pre canvas"); From 69c166c3e944a3cdb8f45597a1ff9cc801a83d21 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 10 Sep 2024 12:15:48 +1000 Subject: [PATCH 27/33] minor fixes --- .../powerboard/credit_card/pay.blade.php | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 7183b9561afd..8bbbe0cf3072 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -145,13 +145,7 @@ console.log("finish"); console.log(data); - - const div = document.getElementById('widget'); - - if(div.offsetParent !== null) - process3ds(); - else - processNon3ds(); + process3ds(); }); @@ -194,17 +188,15 @@ document.getElementById('store_card').value = storeCard.value; } - document.getElementById('stepone_submit').click(); + const div = document.getElementById('widget'); + if(div.offsetParent !== null) + document.getElementById('stepone_submit').click(); + else + document.getElementById('server-response').submit(); + }); - function processNon3ds() - { - - document.getElementById('#server-response').submit(); - - } - async function process3ds() { From 953a8b632bfe762c773c96412e0d697ae5081dfd Mon Sep 17 00:00:00 2001 From: David Bomba Date: Tue, 10 Sep 2024 13:51:43 +1000 Subject: [PATCH 28/33] Additional error handlers --- .../CBAPowerBoard/CreditCard.php | 5 +- .../powerboard/credit_card/pay.blade.php | 58 +++++-------------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php index bb416636c401..167b3bf1b3b3 100644 --- a/app/PaymentDrivers/CBAPowerBoard/CreditCard.php +++ b/app/PaymentDrivers/CBAPowerBoard/CreditCard.php @@ -260,7 +260,6 @@ class CreditCard implements LivewireMethodInterface nlog($r->body()); if($r->failed()){ - // return $this->processUnsuccessfulPayment($r); $error_payload = $this->getErrorFromResponse($r); throw new PaymentFailed($error_payload[0], $error_payload[1]); @@ -391,7 +390,9 @@ class CreditCard implements LivewireMethodInterface return $this->processSuccessfulPayment($charge); } - + elseif($charge->error){ + throw new PaymentFailed($charge->error->message, $charge->status); + } } diff --git a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php index 8bbbe0cf3072..fce0cec0d0d3 100644 --- a/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/powerboard/credit_card/pay.blade.php @@ -88,49 +88,15 @@