mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 16:44:29 -04:00
powerboard
This commit is contained in:
parent
a9aa6aea87
commit
1f3c37a76b
28
app/Helpers/Sanitizer.php
Normal file
28
app/Helpers/Sanitizer.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
class Sanitizer
|
||||
{
|
||||
|
||||
public static function removeBlanks($input): array
|
||||
{
|
||||
foreach ($input as &$value) {
|
||||
if (is_array($value)) {
|
||||
// Recursively apply the filter to nested arrays
|
||||
$value = self::removeBlanks($value);
|
||||
}
|
||||
}
|
||||
// Use array_filter to remove empty or null values
|
||||
return array_filter($input);
|
||||
}
|
||||
}
|
@ -12,15 +12,18 @@
|
||||
|
||||
namespace App\PaymentDrivers\CBAPowerBoard;
|
||||
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\PaymentHash;
|
||||
use App\Models\PaymentType;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use App\PaymentDrivers\CBAPowerBoardPaymentDriver;
|
||||
use App\PaymentDrivers\CBAPowerBoard\Models\Charge;
|
||||
use App\PaymentDrivers\Common\LivewireMethodInterface;
|
||||
use App\PaymentDrivers\CBAPowerBoard\Models\PaymentSource;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
|
||||
class CreditCard implements LivewireMethodInterface
|
||||
{
|
||||
@ -43,12 +46,12 @@ class CreditCard implements LivewireMethodInterface
|
||||
|
||||
private function getCustomer(): array
|
||||
{
|
||||
return [
|
||||
$data = [
|
||||
'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',
|
||||
// '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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
87
app/PaymentDrivers/CBAPowerBoard/Models/Charge.php
Normal file
87
app/PaymentDrivers/CBAPowerBoard/Models/Charge.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
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[] */
|
||||
public array $transactions;
|
||||
/** @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;
|
||||
|
||||
/**
|
||||
* @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,
|
||||
array $transactions,
|
||||
bool $one_off,
|
||||
bool $archived,
|
||||
Customer $customer,
|
||||
bool $capture,
|
||||
string $status,
|
||||
array $items,
|
||||
) {
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
96
app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php
Normal file
96
app/PaymentDrivers/CBAPowerBoard/Models/PaymentSource.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\CBAPowerBoard\Models;
|
||||
|
||||
class PaymentSource
|
||||
{
|
||||
/** @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;
|
||||
/** @var ?string */
|
||||
public ?string $gateway_id;
|
||||
|
||||
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,
|
||||
?string $gateway_id
|
||||
) {
|
||||
$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;
|
||||
$this->gateway_id = $gateway_id;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
64
app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php
Normal file
64
app/PaymentDrivers/CBAPowerBoard/Models/Transaction.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\CBAPowerBoard\Models;
|
||||
|
||||
class Transactions
|
||||
{
|
||||
/** @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;
|
||||
}
|
||||
}
|
@ -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: {
|
||||
|
@ -16,6 +16,8 @@
|
||||
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
|
||||
|
||||
<input type="hidden" name="token">
|
||||
<input type="hidden" name="browser_details">
|
||||
<input type="hidden" name="charge">
|
||||
<button type="submit" class="hidden" id="stub">Submit</button>
|
||||
</form>
|
||||
|
||||
@ -63,6 +65,7 @@
|
||||
<div id="powerboard-payment-container" class="w-full">
|
||||
<div id="widget" style="block"></div>
|
||||
</div>
|
||||
|
||||
@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; //
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
|
Loading…
x
Reference in New Issue
Block a user