diff --git a/app/PaymentDrivers/Braintree/ACH.php b/app/PaymentDrivers/Braintree/ACH.php
index bbd854291d71..e5527049a5e8 100644
--- a/app/PaymentDrivers/Braintree/ACH.php
+++ b/app/PaymentDrivers/Braintree/ACH.php
@@ -20,11 +20,12 @@ use App\Models\Payment;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\BraintreePaymentDriver;
+use App\PaymentDrivers\Common\LivewireMethodInterface;
use App\PaymentDrivers\Common\MethodInterface;
use App\Utils\Traits\MakesHash;
use Illuminate\Http\Request;
-class ACH implements MethodInterface
+class ACH implements MethodInterface, LivewireMethodInterface
{
use MakesHash;
@@ -97,10 +98,7 @@ class ACH implements MethodInterface
public function paymentView(array $data)
{
- $data['gateway'] = $this->braintree;
- $data['currency'] = $this->braintree->client->getCurrencyCode();
- $data['payment_method_id'] = GatewayType::BANK_TRANSFER;
- $data['amount'] = $this->braintree->payment_hash->data->amount_with_fee;
+ $data = $this->paymentData($data);
return render('gateways.braintree.ach.pay', $data);
}
@@ -181,4 +179,24 @@ class ACH implements MethodInterface
throw new PaymentFailed($response->transaction->additionalProcessorResponse, $response->transaction->processorResponseCode);
}
+ /**
+ * @inheritDoc
+ */
+ public function livewirePaymentView(array $data): string
+ {
+ return 'gateways.braintree.ach.pay_livewire';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function paymentData(array $data): array
+ {
+ $data['gateway'] = $this->braintree;
+ $data['currency'] = $this->braintree->client->getCurrencyCode();
+ $data['payment_method_id'] = GatewayType::BANK_TRANSFER;
+ $data['amount'] = $this->braintree->payment_hash->data->amount_with_fee;
+
+ return $data;
+ }
}
diff --git a/app/PaymentDrivers/Braintree/CreditCard.php b/app/PaymentDrivers/Braintree/CreditCard.php
index 3ab0fdbe3de7..5bf091022703 100644
--- a/app/PaymentDrivers/Braintree/CreditCard.php
+++ b/app/PaymentDrivers/Braintree/CreditCard.php
@@ -21,8 +21,9 @@ use App\Models\Payment;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\BraintreePaymentDriver;
+use App\PaymentDrivers\Common\LivewireMethodInterface;
-class CreditCard
+class CreditCard implements LivewireMethodInterface
{
/**
* @var BraintreePaymentDriver
@@ -76,17 +77,7 @@ class CreditCard
public function paymentView(array $data)
{
- $data['gateway'] = $this->braintree;
- $data['client_token'] = $this->braintree->gateway->clientToken()->generate();
- $data['threeds'] = $this->threeDParameters($data);
- $data['threeds_enable'] = $this->braintree->company_gateway->getConfigField('threeds') ? "true" : "false";
-
- if ($this->braintree->company_gateway->getConfigField('merchantAccountId')) {
- /** https://developer.paypal.com/braintree/docs/reference/request/client-token/generate#merchant_account_id */
- $data['client_token'] = $this->braintree->gateway->clientToken()->generate([ //@phpstan-ignore-line
- 'merchantAccountId' => $this->braintree->company_gateway->getConfigField('merchantAccountId'),
- ]);
- }
+ $data = $this->paymentData($data);
return render('gateways.braintree.credit_card.pay', $data);
}
@@ -278,4 +269,32 @@ class CreditCard
return $this->braintree->processInternallyFailedPayment($this->braintree, $e);
}
}
+
+ /**
+ * @inheritDoc
+ */
+ public function livewirePaymentView(array $data): string
+ {
+ return 'gateways.braintree.credit_card.pay_livewire';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function paymentData(array $data): array
+ {
+ $data['gateway'] = $this->braintree;
+ $data['client_token'] = $this->braintree->gateway->clientToken()->generate();
+ $data['threeds'] = $this->threeDParameters($data);
+ $data['threeds_enable'] = $this->braintree->company_gateway->getConfigField('threeds') ? "true" : "false";
+
+ if ($this->braintree->company_gateway->getConfigField('merchantAccountId')) {
+ /** https://developer.paypal.com/braintree/docs/reference/request/client-token/generate#merchant_account_id */
+ $data['client_token'] = $this->braintree->gateway->clientToken()->generate([
+ 'merchantAccountId' => $this->braintree->company_gateway->getConfigField('merchantAccountId'),
+ ]);
+ }
+
+ return $data;
+ }
}
diff --git a/app/PaymentDrivers/Braintree/PayPal.php b/app/PaymentDrivers/Braintree/PayPal.php
index 6de57c1f15e9..2ad38515484d 100644
--- a/app/PaymentDrivers/Braintree/PayPal.php
+++ b/app/PaymentDrivers/Braintree/PayPal.php
@@ -10,8 +10,9 @@ use App\Models\Payment;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\BraintreePaymentDriver;
+use App\PaymentDrivers\Common\LivewireMethodInterface;
-class PayPal
+class PayPal implements LivewireMethodInterface
{
/**
* @var BraintreePaymentDriver
@@ -45,8 +46,7 @@ class PayPal
*/
public function paymentView(array $data)
{
- $data['gateway'] = $this->braintree;
- $data['client_token'] = $this->braintree->gateway->clientToken()->generate();
+ $data = $this->paymentData($data);
return render('gateways.braintree.paypal.pay', $data);
}
@@ -188,4 +188,23 @@ class PayPal
return $this->braintree->processInternallyFailedPayment($this->braintree, $e);
}
}
+
+ /**
+ * @inheritDoc
+ */
+ public function livewirePaymentView(array $data): string
+ {
+ return 'gateways.braintree.paypal.pay_livewire';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function paymentData(array $data): array
+ {
+ $data['gateway'] = $this->braintree;
+ $data['client_token'] = $this->braintree->gateway->clientToken()->generate();
+
+ return $data;
+ }
}
diff --git a/public/build/assets/braintree-credit-card-1c3f3108.js b/public/build/assets/braintree-credit-card-1c3f3108.js
deleted file mode 100644
index f9a4e882261c..000000000000
--- a/public/build/assets/braintree-credit-card-1c3f3108.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * Invoice Ninja (https://invoiceninja.com).
- *
- * @link https://github.com/invoiceninja/invoiceninja source repository
- *
- * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
- *
- * @license https://www.elastic.co/licensing/elastic-license
- */class i{initBraintreeDataCollector(){window.braintree.client.create({authorization:document.querySelector("meta[name=client-token]").content},function(e,n){window.braintree.dataCollector.create({client:n,paypal:!0},function(t,a){t||(document.querySelector("input[name=client-data]").value=a.deviceData)})})}mountBraintreePaymentWidget(){window.braintree.dropin.create({authorization:document.querySelector("meta[name=client-token]").content,container:"#dropin-container",threeDSecure:document.querySelector("input[name=threeds_enable]").value.toLowerCase()==="true"},this.handleCallback)}handleCallback(e,n){if(e){console.error(e);return}let t=document.getElementById("pay-now");params=JSON.parse(document.querySelector("input[name=threeds]").value),t.addEventListener("click",()=>{n.requestPaymentMethod({threeDSecure:{challengeRequested:!0,amount:params.amount,email:params.email,billingAddress:{givenName:params.billingAddress.givenName,surname:params.billingAddress.surname,phoneNumber:params.billingAddress.phoneNumber,streetAddress:params.billingAddress.streetAddress,extendedAddress:params.billingAddress.extendedAddress,locality:params.billingAddress.locality,region:params.billingAddress.region,postalCode:params.billingAddress.postalCode,countryCodeAlpha2:params.billingAddress.countryCodeAlpha2}}},function(a,r){if(a){console.log(a),dropin.clearSelectedPaymentMethod(),alert("There was a problem verifying this card, please contact your merchant");return}if(document.querySelector("input[name=threeds_enable]").value==="true"&&!r.liabilityShifted){console.log("Liability did not shift",r),alert("There was a problem verifying this card, please contact your merchant");return}t.disabled=!0,t.querySelector("svg").classList.remove("hidden"),t.querySelector("span").classList.add("hidden"),document.querySelector("input[name=gateway_response]").value=JSON.stringify(r);let d=document.querySelector('input[name="token-billing-checkbox"]:checked');d&&(document.querySelector('input[name="store_card"]').value=d.value),document.getElementById("server-response").submit()})})}handle(){this.initBraintreeDataCollector(),this.mountBraintreePaymentWidget(),Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(n=>n.addEventListener("click",t=>{document.getElementById("dropin-container").classList.add("hidden"),document.getElementById("save-card--container").style.display="none",document.querySelector("input[name=token]").value=t.target.dataset.token,document.getElementById("pay-now-with-token").classList.remove("hidden"),document.getElementById("pay-now").classList.add("hidden")})),document.getElementById("toggle-payment-with-credit-card").addEventListener("click",n=>{document.getElementById("dropin-container").classList.remove("hidden"),document.getElementById("save-card--container").style.display="grid",document.querySelector("input[name=token]").value="",document.getElementById("pay-now-with-token").classList.add("hidden"),document.getElementById("pay-now").classList.remove("hidden")});let e=document.getElementById("pay-now-with-token");e.addEventListener("click",n=>{e.disabled=!0,e.querySelector("svg").classList.remove("hidden"),e.querySelector("span").classList.add("hidden"),document.getElementById("server-response").submit()})}}new i().handle();
diff --git a/public/build/assets/braintree-credit-card-2ba935f9.js b/public/build/assets/braintree-credit-card-2ba935f9.js
new file mode 100644
index 000000000000..d9e5d9b3b0e1
--- /dev/null
+++ b/public/build/assets/braintree-credit-card-2ba935f9.js
@@ -0,0 +1,9 @@
+import{i as e,w as n}from"./wait-8f4ae121.js";/**
+ * Invoice Ninja (https://invoiceninja.com).
+ *
+ * @link https://github.com/invoiceninja/invoiceninja source repository
+ *
+ * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
+ *
+ * @license https://www.elastic.co/licensing/elastic-license
+ */function t(){console.log("boot",document.querySelector("meta[name=client-token]"))}e()?t():n("#braintree-credit-card-payment","meta[name=client-token]").then(()=>t());
diff --git a/public/build/assets/braintree-paypal-45391805.js b/public/build/assets/braintree-paypal-16e2f577.js
similarity index 89%
rename from public/build/assets/braintree-paypal-45391805.js
rename to public/build/assets/braintree-paypal-16e2f577.js
index 662aab2a1bc2..d2a70b6d643e 100644
--- a/public/build/assets/braintree-paypal-45391805.js
+++ b/public/build/assets/braintree-paypal-16e2f577.js
@@ -1,4 +1,4 @@
-/**
+import{i as l,w as s}from"./wait-8f4ae121.js";/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
@@ -6,4 +6,4 @@
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
- */class a{initBraintreeDataCollector(){window.braintree.client.create({authorization:document.querySelector("meta[name=client-token]").content},function(e,t){window.braintree.dataCollector.create({client:t,paypal:!0},function(n,o){n||(document.querySelector("input[name=client-data]").value=o.deviceData)})})}static getPaymentDetails(){return{flow:"vault"}}static handleErrorMessage(e){let t=document.getElementById("errors");t.innerText=e,t.hidden=!1}handlePaymentWithToken(){Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(t=>t.addEventListener("click",n=>{document.getElementById("paypal-button").classList.add("hidden"),document.getElementById("save-card--container").style.display="none",document.querySelector("input[name=token]").value=n.target.dataset.token,document.getElementById("pay-now-with-token").classList.remove("hidden"),document.getElementById("pay-now").classList.add("hidden")}));let e=document.getElementById("pay-now-with-token");e.addEventListener("click",t=>{e.disabled=!0,e.querySelector("svg").classList.remove("hidden"),e.querySelector("span").classList.add("hidden"),document.getElementById("server-response").submit()})}handle(){this.initBraintreeDataCollector(),this.handlePaymentWithToken(),braintree.client.create({authorization:document.querySelector("meta[name=client-token]").content}).then(function(e){return braintree.paypalCheckout.create({client:e})}).then(function(e){return e.loadPayPalSDK({vault:!0}).then(function(t){return paypal.Buttons({fundingSource:paypal.FUNDING.PAYPAL,createBillingAgreement:function(){return t.createPayment(a.getPaymentDetails())},onApprove:function(n,o){return t.tokenizePayment(n).then(function(i){let r=document.querySelector('input[name="token-billing-checkbox"]:checked');r&&(document.querySelector('input[name="store_card"]').value=r.value),document.querySelector("input[name=gateway_response]").value=JSON.stringify(i),document.getElementById("server-response").submit()})},onCancel:function(n){},onError:function(n){console.log(n.message),a.handleErrorMessage(n.message)}}).render("#paypal-button")})}).catch(function(e){console.log(e.message),a.handleErrorMessage(e.message)})}}new a().handle();
+ */class a{initBraintreeDataCollector(){window.braintree.client.create({authorization:document.querySelector("meta[name=client-token]").content},function(e,t){window.braintree.dataCollector.create({client:t,paypal:!0},function(n,o){n||(document.querySelector("input[name=client-data]").value=o.deviceData)})})}static getPaymentDetails(){return{flow:"vault"}}static handleErrorMessage(e){let t=document.getElementById("errors");t.innerText=e,t.hidden=!1}handlePaymentWithToken(){Array.from(document.getElementsByClassName("toggle-payment-with-token")).forEach(t=>t.addEventListener("click",n=>{document.getElementById("paypal-button").classList.add("hidden"),document.getElementById("save-card--container").style.display="none",document.querySelector("input[name=token]").value=n.target.dataset.token,document.getElementById("pay-now-with-token").classList.remove("hidden"),document.getElementById("pay-now").classList.add("hidden")}));let e=document.getElementById("pay-now-with-token");e.addEventListener("click",t=>{e.disabled=!0,e.querySelector("svg").classList.remove("hidden"),e.querySelector("span").classList.add("hidden"),document.getElementById("server-response").submit()})}handle(){this.initBraintreeDataCollector(),this.handlePaymentWithToken(),braintree.client.create({authorization:document.querySelector("meta[name=client-token]").content}).then(function(e){return braintree.paypalCheckout.create({client:e})}).then(function(e){return e.loadPayPalSDK({vault:!0}).then(function(t){return paypal.Buttons({fundingSource:paypal.FUNDING.PAYPAL,createBillingAgreement:function(){return t.createPayment(a.getPaymentDetails())},onApprove:function(n,o){return t.tokenizePayment(n).then(function(c){let r=document.querySelector('input[name="token-billing-checkbox"]:checked');r&&(document.querySelector('input[name="store_card"]').value=r.value),document.querySelector("input[name=gateway_response]").value=JSON.stringify(c),document.getElementById("server-response").submit()})},onCancel:function(n){},onError:function(n){console.log(n.message),a.handleErrorMessage(n.message)}}).render("#paypal-button")})}).catch(function(e){console.log(e.message),a.handleErrorMessage(e.message)})}}function i(){new a().handle()}l()?i():s("#braintree-paypal-payment").then(()=>i());
diff --git a/public/build/manifest.json b/public/build/manifest.json
index c6b158c25559..c423e56ed51b 100644
--- a/public/build/manifest.json
+++ b/public/build/manifest.json
@@ -75,12 +75,18 @@
"src": "resources/js/clients/payments/authorize-credit-card-payment.js"
},
"resources/js/clients/payments/braintree-credit-card.js": {
- "file": "assets/braintree-credit-card-1c3f3108.js",
+ "file": "assets/braintree-credit-card-2ba935f9.js",
+ "imports": [
+ "_wait-8f4ae121.js"
+ ],
"isEntry": true,
"src": "resources/js/clients/payments/braintree-credit-card.js"
},
"resources/js/clients/payments/braintree-paypal.js": {
- "file": "assets/braintree-paypal-45391805.js",
+ "file": "assets/braintree-paypal-16e2f577.js",
+ "imports": [
+ "_wait-8f4ae121.js"
+ ],
"isEntry": true,
"src": "resources/js/clients/payments/braintree-paypal.js"
},
diff --git a/resources/js/clients/payments/braintree-credit-card.js b/resources/js/clients/payments/braintree-credit-card.js
index 1c7dacac0489..2fb5e672ef8f 100644
--- a/resources/js/clients/payments/braintree-credit-card.js
+++ b/resources/js/clients/payments/braintree-credit-card.js
@@ -8,6 +8,7 @@
* @license https://www.elastic.co/licensing/elastic-license
*/
+import { wait, instant } from '../wait';
class BraintreeCreditCard {
initBraintreeDataCollector() {
@@ -43,8 +44,7 @@ class BraintreeCreditCard {
}
let payNow = document.getElementById('pay-now');
-
- params = JSON.parse(document.querySelector('input[name=threeds]').value);
+ let params = JSON.parse(document.querySelector('input[name=threeds]').value);
payNow.addEventListener('click', () => {
dropinInstance.requestPaymentMethod({
@@ -138,4 +138,8 @@ class BraintreeCreditCard {
}
}
-new BraintreeCreditCard().handle();
+function boot() {
+ new BraintreeCreditCard().handle();
+}
+
+instant() ? boot() : wait('#braintree-credit-card-payment', 'meta[name=client-token]').then(() => boot());
diff --git a/resources/js/clients/payments/braintree-paypal.js b/resources/js/clients/payments/braintree-paypal.js
index affaf1cb26b2..40cabce5ae0b 100644
--- a/resources/js/clients/payments/braintree-paypal.js
+++ b/resources/js/clients/payments/braintree-paypal.js
@@ -8,6 +8,8 @@
* @license https://www.elastic.co/licensing/elastic-license
*/
+import { wait, instant } from '../wait';
+
class BraintreePayPal {
initBraintreeDataCollector() {
window.braintree.client.create({
@@ -119,4 +121,8 @@ class BraintreePayPal {
}
}
-new BraintreePayPal().handle();
+function boot() {
+ new BraintreePayPal().handle();
+}
+
+instant() ? boot() : wait('#braintree-paypal-payment').then(() => boot());
diff --git a/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php
index e9f1c44f9b4c..771a5f3e5530 100644
--- a/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php
+++ b/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php
@@ -2,6 +2,7 @@
@section('gateway_head')
+
{{-- --}}
diff --git a/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php b/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php
index b405cebafed9..bbc1b6b0398c 100644
--- a/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php
+++ b/resources/views/portal/ninja2020/gateways/braintree/paypal/pay.blade.php
@@ -2,6 +2,7 @@
@section('gateway_head')
+