diff --git a/app/PaymentDrivers/BaseDriver.php b/app/PaymentDrivers/BaseDriver.php index 9c6238c506c3..778ebc5ff6f1 100644 --- a/app/PaymentDrivers/BaseDriver.php +++ b/app/PaymentDrivers/BaseDriver.php @@ -71,7 +71,7 @@ class BaseDriver extends AbstractPaymentDriver public $payment_method; /* PaymentHash */ - public $payment_hash; + public PaymentHash $payment_hash; /* Array of payment methods */ public static $methods = []; diff --git a/app/PaymentDrivers/Stripe/BrowserPay.php b/app/PaymentDrivers/Stripe/BrowserPay.php new file mode 100644 index 000000000000..edb2f16a945a --- /dev/null +++ b/app/PaymentDrivers/Stripe/BrowserPay.php @@ -0,0 +1,215 @@ +stripe = $stripe; + + $this->stripe->init(); + + $this->ensureApplePayDomainIsValidated(); + } + + /** + * Authorization page for browser pay. + * + * @param array $data + * @return RedirectResponse + */ + public function authorizeView(array $data): RedirectResponse + { + return redirect()->route('client.payment_methods.index'); + } + + /** + * Handle the authorization for browser pay. + * + * @param Request $request + * @return RedirectResponse + */ + public function authorizeResponse(Request $request): RedirectResponse + { + return redirect()->route('client.payment_methods.index'); + } + + public function paymentView(array $data): View + { + $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' => $this->stripe->decodeUnicodeString(ctrans('texts.invoices') . ': ' . collect($data['invoices'])->pluck('invoice_number')), + ]; + + $data['gateway'] = $this->stripe; + $data['pi_client_secret'] = $this->stripe->createPaymentIntent($payment_intent_data)->client_secret; + + $data['payment_request_data'] = [ + 'country' => $this->stripe->client->country->iso_3166_2, + 'currency' => strtolower( + $this->stripe->client->getCurrencyCode() + ), + 'total' => [ + 'label' => $payment_intent_data['description'], + 'amount' => $payment_intent_data['amount'], + ], + 'requestPayerName' => true, + 'requestPayerEmail' => true + ]; + + return render('gateways.stripe.browser_pay.pay', $data); + } + + /** + * Handle payment response for browser pay. + * + * @param PaymentResponseRequest $request + * @return RedirectResponse|App\PaymentDrivers\Stripe\never + */ + public function paymentResponse(PaymentResponseRequest $request) + { + $gateway_response = json_decode($request->gateway_response); + + $this->stripe->payment_hash + ->withData('gateway_response', $gateway_response) + ->withData('payment_intent', PaymentIntent::retrieve($gateway_response->id, $this->stripe->stripe_connect_auth)); + + if ($gateway_response->status === 'succeeded') { + return $this->processSuccessfulPayment(); + } + + return $this->processUnsuccessfulPayment(); + } + + /** + * Handle successful payment for browser pay. + * + * @return RedirectResponse + */ + protected function processSuccessfulPayment() + { + $gateway_response = $this->stripe->payment_hash->data->gateway_response; + $payment_intent = $this->stripe->payment_hash->data->payment_intent; + + $this->stripe->logSuccessfulGatewayResponse(['response' => $gateway_response, 'data' => $this->stripe->payment_hash], SystemLog::TYPE_STRIPE); + + $payment_method = $this->stripe->getStripePaymentMethod($gateway_response->payment_method); + + $data = [ + 'payment_method' => $gateway_response->payment_method, + 'payment_type' => PaymentType::parseCardType(strtolower($payment_method->card->brand)), + 'amount' => $this->stripe->convertFromStripeAmount($gateway_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()), + 'transaction_reference' => optional($payment_intent->charges->data[0])->id, + 'gateway_type_id' => GatewayType::APPLE_PAY, + ]; + + $this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['amount' => $data['amount']]); + $this->stripe->payment_hash->save(); + + $payment = $this->stripe->createPayment($data, Payment::STATUS_COMPLETED); + + SystemLogger::dispatch( + ['response' => $gateway_response, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_STRIPE, + $this->stripe->client, + $this->stripe->client->company, + ); + + return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]); + } + + /** + * Handle unsuccessful payment for browser pay. + * + * @return never + */ + protected function processUnsuccessfulPayment() + { + $server_response = $this->stripe->payment_hash->data->gateway_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); + } + + /** + * Ensure Apple Pay domain is verified. + * + * @return void + * @throws ApiErrorException + */ + protected function ensureApplePayDomainIsValidated() + { + $config = $this->stripe->company_gateway->getConfig(); + + if (property_exists($config, 'apple_pay_domain_id')) { + return; + } + + $domain = config('ninja.app_url'); + + if (Ninja::isHosted()) { + $domain = isset($this->stripe_driver->company_gateway->company->portal_domain) + ? $this->stripe_driver->company_gateway->company->portal_domain + : $this->stripe_driver->company_gateway->company->domain(); + } + + $response = ApplePayDomain::create([ + 'domain_name' => $domain, + ]); + + $config->apple_pay_domain_id = $response->id; + + $this->stripe->company_gateway->setConfig($config); + + $this->stripe->company_gateway->save(); + } +} diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 6ae31452ba21..7ac9ab9d0411 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -40,6 +40,7 @@ use App\PaymentDrivers\Stripe\EPS; use App\PaymentDrivers\Stripe\Bancontact; use App\PaymentDrivers\Stripe\BECS; use App\PaymentDrivers\Stripe\ACSS; +use App\PaymentDrivers\Stripe\BrowserPay; use App\PaymentDrivers\Stripe\UpdatePaymentMethods; use App\PaymentDrivers\Stripe\Utilities; use App\Utils\Traits\MakesHash; @@ -82,7 +83,7 @@ class StripePaymentDriver extends BaseDriver GatewayType::BANK_TRANSFER => ACH::class, GatewayType::ALIPAY => Alipay::class, GatewayType::SOFORT => SOFORT::class, - GatewayType::APPLE_PAY => ApplePay::class, + GatewayType::APPLE_PAY => BrowserPay::class, GatewayType::SEPA => SEPA::class, GatewayType::PRZELEWY24 => PRZELEWY24::class, GatewayType::GIROPAY => GIROPAY::class, @@ -139,7 +140,7 @@ class StripePaymentDriver extends BaseDriver { $types = [ // GatewayType::CRYPTO, - GatewayType::CREDIT_CARD + GatewayType::CREDIT_CARD, ]; if ($this->client @@ -218,6 +219,14 @@ class StripePaymentDriver extends BaseDriver && in_array($this->client->country->iso_3166_3, ["CAN", "USA"])) $types[] = GatewayType::ACSS; + if ( + $this->client + && isset($this->client->country) + && in_array($this->client->country->iso_3166_2, ['AE', 'AT', 'AU', 'BE', 'BG', 'BR', 'CA', 'CH', 'CI', 'CR', 'CY', 'CZ', 'DE', 'DK', 'DO', 'EE', 'ES', 'FI', 'FR', 'GB', 'GI', 'GR', 'GT', 'HK', 'HU', 'ID', 'IE', 'IN', 'IT', 'JP', 'LI', 'LT', 'LU', 'LV', 'MT', 'MX', 'MY', 'NL', 'NO', 'NZ', 'PE', 'PH', 'PL', 'PT', 'RO', 'SE', 'SG', 'SI', 'SK', 'SN', 'TH', 'TT', 'US', 'UY']) + ) { + $types[] = GatewayType::APPLE_PAY; + } + return $types; } diff --git a/public/.well-known/apple-developer-merchantid-domain-association b/public/.well-known/apple-developer-merchantid-domain-association new file mode 100644 index 000000000000..2ff95c962810 --- /dev/null +++ b/public/.well-known/apple-developer-merchantid-domain-association @@ -0,0 +1 @@ +7B227073704964223A2239373943394538343346343131343044463144313834343232393232313734313034353044314339464446394437384337313531303944334643463542433731222C2276657273696F6E223A312C22637265617465644F6E223A313536363233343735303036312C227369676E6174757265223A22333038303036303932613836343838366637306430313037303261303830333038303032303130313331306633303064303630393630383634383031363530333034303230313035303033303830303630393261383634383836663730643031303730313030303061303830333038323033653333303832303338386130303330323031303230323038346333303431343935313964353433363330306130363038326138363438636533643034303330323330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333031653137306433313339333033353331333833303331333333323335333735613137306433323334333033353331333633303331333333323335333735613330356633313235333032333036303335353034303330633163363536333633326437333664373032643632373236663662363537323264373336393637366535663535343333343264353035323466343433313134333031323036303335353034306230633062363934663533323035333739373337343635366437333331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533333035393330313330363037326138363438636533643032303130363038326138363438636533643033303130373033343230303034633231353737656465626436633762323231386636386464373039306131323138646337623062643666326332383364383436303935643934616634613534313162383334323065643831316633343037653833333331663163353463336637656233323230643662616435643465666634393238393839336537633066313361333832303231313330383230323064333030633036303335353164313330313031666630343032333030303330316630363033353531643233303431383330313638303134323366323439633434663933653465663237653663346636323836633366613262626664326534623330343530363038326230363031303530353037303130313034333933303337333033353036303832623036303130353035303733303031383632393638373437343730336132663266366636333733373032653631373037303663363532653633366636643266366636333733373033303334326436313730373036633635363136393633363133333330333233303832303131643036303335353164323030343832303131343330383230313130333038323031306330363039326138363438383666373633363430353031333038316665333038316333303630383262303630313035303530373032303233303831623630633831623335323635366336393631366536333635323036663665323037343638363937333230363336353732373436393636363936333631373436353230363237393230363136653739323037303631373237343739323036313733373337353664363537333230363136333633363537303734363136653633363532303666363632303734363836353230373436383635366532303631373037303663363936333631363236633635323037333734363136653634363137323634323037343635373236643733323036313665363432303633366636653634363937343639366636653733323036663636323037353733363532633230363336353732373436393636363936333631373436353230373036663663363936333739323036313665363432303633363537323734363936363639363336313734363936663665323037303732363136333734363936333635323037333734363137343635366436353665373437333265333033363036303832623036303130353035303730323031313632613638373437343730336132663266373737373737326536313730373036633635326536333666366432663633363537323734363936363639363336313734363536313735373436383666373236393734373932663330333430363033353531643166303432643330326233303239613032376130323538363233363837343734373033613266326636333732366332653631373037303663363532653633366636643266363137303730366336353631363936333631333332653633373236633330316430363033353531643065303431363034313439343537646236666435373438313836383938393736326637653537383530376537396235383234333030653036303335353164306630313031666630343034303330323037383033303066303630393261383634383836663736333634303631643034303230353030333030613036303832613836343863653364303430333032303334393030333034363032323130306265303935373166653731653165373335623535653561666163623463373266656234343566333031383532323263373235313030326236316562643666353530323231303064313862333530613564643664643665623137343630333562313165623263653837636661336536616636636264383338303839306463383263646461613633333038323032656533303832303237356130303330323031303230323038343936643266626633613938646139373330306130363038326138363438636533643034303330323330363733313162333031393036303335353034303330633132343137303730366336353230353236663666373432303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330316531373064333133343330333533303336333233333334333633333330356131373064333233393330333533303336333233333334333633333330356133303761333132653330326330363033353530343033306332353431373037303663363532303431373037303663363936333631373436393666366532303439366537343635363737323631373436393666366532303433343132303264323034373333333132363330323430363033353530343062306331643431373037303663363532303433363537323734363936363639363336313734363936663665323034313735373436383666373236393734373933313133333031313036303335353034306130633061343137303730366336353230343936653633326533313062333030393036303335353034303631333032353535333330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030346630313731313834313964373634383564353161356532353831303737366538383061326566646537626165346465303864666334623933653133333536643536363562333561653232643039373736306432323465376262613038666437363137636538386362373662623636373062656338653832393834666635343435613338316637333038316634333034363036303832623036303130353035303730313031303433613330333833303336303630383262303630313035303530373330303138363261363837343734373033613266326636663633373337303265363137303730366336353265363336663664326636663633373337303330333432643631373037303663363537323666366637343633363136373333333031643036303335353164306530343136303431343233663234396334346639336534656632376536633466363238366333666132626266643265346233303066303630333535316431333031303166663034303533303033303130316666333031663036303335353164323330343138333031363830313462626230646561313538333338383961613438613939646562656264656261666461636232346162333033373036303335353164316630343330333032653330326361303261613032383836323636383734373437303361326632663633373236633265363137303730366336353265363336663664326636313730373036633635373236663666373436333631363733333265363337323663333030653036303335353164306630313031666630343034303330323031303633303130303630613261383634383836663736333634303630323065303430323035303033303061303630383261383634386365336430343033303230333637303033303634303233303361636637323833353131363939623138366662333563333536636136326266663431376564643930663735346461323865626566313963383135653432623738396638393866373962353939663938643534313064386639646539633266653032333033323264643534343231623061333035373736633564663333383362393036376664313737633263323136643936346663363732363938323132366635346638376137643162393963623962303938393231363130363939306630393932316430303030333138323031386233303832303138373032303130313330383138363330376133313265333032633036303335353034303330633235343137303730366336353230343137303730366336393633363137343639366636653230343936653734363536373732363137343639366636653230343334313230326432303437333333313236333032343036303335353034306230633164343137303730366336353230343336353732373436393636363936333631373436393666366532303431373537343638366637323639373437393331313333303131303630333535303430613063306134313730373036633635323034393665363332653331306233303039303630333535303430363133303235353533303230383463333034313439353139643534333633303064303630393630383634383031363530333034303230313035303061303831393533303138303630393261383634383836663730643031303930333331306230363039326138363438383666373064303130373031333031633036303932613836343838366637306430313039303533313066313730643331333933303338333133393331333733313332333333303561333032613036303932613836343838366637306430313039333433313164333031623330306430363039363038363438303136353033303430323031303530306131306130363038326138363438636533643034303330323330326630363039326138363438383666373064303130393034333132323034323062303731303365313430613462386231376262613230316130336163643036396234653431366232613263383066383661383338313435633239373566633131333030613036303832613836343863653364303430333032303434363330343430323230343639306264636637626461663833636466343934396534633035313039656463663334373665303564373261313264376335666538633033303033343464663032323032363764353863393365626233353031333836363062353730373938613064643731313734316262353864626436613138363633353038353431656565393035303030303030303030303030227D \ No newline at end of file diff --git a/public/css/card-js.min.css b/public/css/card-js.min.css index be2167f46033..d5d9b342f8ed 100644 --- a/public/css/card-js.min.css +++ b/public/css/card-js.min.css @@ -1 +1 @@ -.card-js input.card-number{padding-right:48px}.card-js .card-number-wrapper .card-type-icon{height:23px;width:32px;position:absolute;display:block;right:8px;top:7px;background:url(https://cardjs.co.uk/img/cards.png) 0 23px no-repeat;pointer-events:none;opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-ms-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.card-js .card-number-wrapper .show{opacity:1}.card-js .card-number-wrapper .card-type-icon.visa{background-position:0 0}.card-js .card-number-wrapper .card-type-icon.master-card{background-position:-32px 0}.card-js .card-number-wrapper .card-type-icon.american-express{background-position:-64px 0}.card-js .card-number-wrapper .card-type-icon.discover{background-position:-96px 0}.card-js .card-number-wrapper .card-type-icon.diners{background-position:-128px 0}.card-js .card-number-wrapper .card-type-icon.jcb{background-position:-160px 0}.card-js .cvc-container{width:50%;float:right}.card-js .cvc-wrapper{box-sizing:border-box;margin-left:5px}.card-js .cvc-wrapper .cvc{display:block;width:100%}.card-js .expiry-container{width:50%;float:left}.card-js .expiry-wrapper{box-sizing:border-box;margin-right:5px}.card-js .expiry-wrapper .expiry{display:block;width:100%}.card-js .expiry-wrapper .expiry-month{border-top-right-radius:0;border-bottom-right-radius:0;padding-left:30px}.card-js .expiry-wrapper .expiry-year{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.card-js .expiry-wrapper .expiry-month,.card-js .expiry-wrapper .expiry-year{display:inline-block}.card-js .expiry-wrapper .expiry{padding-left:38px}.card-js .icon{position:absolute;display:block;width:24px;height:17px;left:8px;top:10px;pointer-events:none}.card-js .icon.right{right:8px;left:auto}.card-js .icon.popup{cursor:pointer;pointer-events:auto}.card-js .icon .svg{fill:#888}.card-js .icon.popup .svg{fill:#aaa!important}.card-js .card-number-wrapper,.card-js .name-wrapper{margin-bottom:15px;width:100%}.card-js .card-number-wrapper,.card-js .cvc-wrapper,.card-js .expiry-wrapper,.card-js .name-wrapper{-webkit-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-moz-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-ms-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-o-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);position:relative}.card-js .card-number-wrapper,.card-js .cvc-container,.card-js .expiry-container,.card-js .name-wrapper{display:inline-block}.card-js::after{content:' ';display:table;clear:both}.card-js input,.card-js select{color:#676767;font-size:15px;font-weight:300;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;height:36px;border:1px solid #d9d9d9;border-radius:4px;box-shadow:none;background-color:#FDFDFD;box-sizing:border-box;padding:0;-webkit-transition:border-color .15s linear,box-shadow .15s linear;-moz-transition:border-color .15s linear,box-shadow .15s linear;-ms-transition:border-color .15s linear,box-shadow .15s linear;-o-transition:border-color .15s linear,box-shadow .15s linear;transition:border-color .15s linear,box-shadow .15s linear}.card-js select{-moz-appearance:none;text-indent:.01px;text-overflow:''}.card-js input[disabled],.card-js select[disabled]{background-color:#eee;color:#555}.card-js select option[hidden]{color:#ABA9A9}.card-js input:focus,.card-js select:focus{background-color:#fff;outline:0;border-color:#66afe9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.card-js input[readonly=readonly]:not([disabled]),.card-js input[readonly]:not([disabled]){background-color:#fff;cursor:pointer}.card-js .has-error input,.card-js .has-error input:focus{border-color:#F64B2F;box-shadow:none}.card-js input.card-number,.card-js input.cvc,.card-js input.name{padding-left:38px;width:100%}.card-js.stripe .icon .svg{fill:#559A28} \ No newline at end of file +.card-js input.card-number{padding-right:48px}.card-js .card-number-wrapper .card-type-icon{height:23px;width:32px;position:absolute;display:block;right:8px;top:7px;background:url(https://cardjs.co.uk/img/cards.png) 0 23px no-repeat;pointer-events:none;opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-ms-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.card-js .card-number-wrapper .show{opacity:1}.card-js .card-number-wrapper .card-type-icon.visa{background-position:0 0}.card-js .card-number-wrapper .card-type-icon.master-card{background-position:-32px 0}.card-js .card-number-wrapper .card-type-icon.american-express{background-position:-64px 0}.card-js .card-number-wrapper .card-type-icon.discover{background-position:-96px 0}.card-js .card-number-wrapper .card-type-icon.diners{background-position:-128px 0}.card-js .card-number-wrapper .card-type-icon.jcb{background-position:-160px 0}.card-js .cvc-container{width:50%;float:right}.card-js .cvc-wrapper{box-sizing:border-box;margin-left:5px}.card-js .cvc-wrapper .cvc{display:block;width:100%}.card-js .expiry-container{width:50%;float:left}.card-js .expiry-wrapper{box-sizing:border-box;margin-right:5px}.card-js .expiry-wrapper .expiry{display:block;width:100%}.card-js .expiry-wrapper .expiry-month{border-top-right-radius:0;border-bottom-right-radius:0;padding-left:30px}.card-js .expiry-wrapper .expiry-year{border-top-left-radius:0;border-bottom-left-radius:0;border-left:0}.card-js .expiry-wrapper .expiry-month,.card-js .expiry-wrapper .expiry-year{display:inline-block}.card-js .expiry-wrapper .expiry{padding-left:38px}.card-js .icon{position:absolute;display:block;width:24px;height:17px;left:8px;top:10px;pointer-events:none}.card-js .icon.right{right:8px;left:auto}.card-js .icon.popup{cursor:pointer;pointer-events:auto}.card-js .icon .svg{fill:#888}.card-js .icon.popup .svg{fill:#aaa!important}.card-js .card-number-wrapper,.card-js .name-wrapper{margin-bottom:15px;width:100%}.card-js .card-number-wrapper,.card-js .cvc-wrapper,.card-js .expiry-wrapper,.card-js .name-wrapper{-webkit-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-moz-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-ms-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);-o-box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);box-shadow:0 1px 0 rgba(255,255,255,.7),inset 0 1px 0 rgba(255,255,255,.7);position:relative}.card-js .card-number-wrapper,.card-js .cvc-container,.card-js .expiry-container,.card-js .name-wrapper{display:inline-block}.card-js::after{content:' ';display:table;clear:both}.card-js input,.card-js select{color:#676767;font-size:15px;font-weight:300;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;height:36px;border:1px solid #d9d9d9;border-radius:4px;box-shadow:none;background-color:#fdfdfd;box-sizing:border-box;padding:0;-webkit-transition:border-color .15s linear,box-shadow .15s linear;-moz-transition:border-color .15s linear,box-shadow .15s linear;-ms-transition:border-color .15s linear,box-shadow .15s linear;-o-transition:border-color .15s linear,box-shadow .15s linear;transition:border-color .15s linear,box-shadow .15s linear}.card-js select{-moz-appearance:none;text-indent:.01px;text-overflow:''}.card-js input[disabled],.card-js select[disabled]{background-color:#eee;color:#555}.card-js select option[hidden]{color:#aba9a9}.card-js input:focus,.card-js select:focus{background-color:#fff;outline:0;border-color:#66afe9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.card-js input[readonly=readonly]:not([disabled]),.card-js input[readonly]:not([disabled]){background-color:#fff;cursor:pointer}.card-js .has-error input,.card-js .has-error input:focus{border-color:#f64b2f;box-shadow:none}.card-js input.card-number,.card-js input.cvc,.card-js input.name{padding-left:38px;width:100%}.card-js.stripe .icon .svg{fill:#559A28} diff --git a/public/js/clients/payments/stripe-browserpay.js b/public/js/clients/payments/stripe-browserpay.js new file mode 100644 index 000000000000..9598eb1892ea --- /dev/null +++ b/public/js/clients/payments/stripe-browserpay.js @@ -0,0 +1,2 @@ +/*! For license information please see stripe-browserpay.js.LICENSE.txt */ +(()=>{function e(e,t){for(var n=0;n { + if (result) { + return this.paymentRequestButton.mount( + '#payment-request-button' + ); + } + + document.querySelector('#errors').innerHTML = JSON.parse( + document.querySelector('meta[name=no-available-methods]') + ?.content + ); + + document.querySelector('#errors').hidden = false; + }); + + this.handlePaymentRequestEvents(this.stripe, this.clientSecret); + } +} + +new StripeBrowserPay().handle(); diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index e730257a298d..d211e72d2c29 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4336,6 +4336,8 @@ $LANG = array( 'acss' => 'Pre-authorized debit payments', 'invalid_amount' => 'Invalid amount. Number/Decimal values only.', 'client_payment_failure_body' => 'Payment for Invoice :invoice for amount :amount failed.', + 'browser_pay' => 'Google Pay, Apple Pay, Microsoft Pay', + 'no_available_methods' => 'We can\'t find any credit cards on your device. Read more about this.' ); return $LANG; diff --git a/resources/views/portal/ninja2020/gateways/stripe/browser_pay/pay.blade.php b/resources/views/portal/ninja2020/gateways/stripe/browser_pay/pay.blade.php new file mode 100644 index 000000000000..24fd269d76b9 --- /dev/null +++ b/resources/views/portal/ninja2020/gateways/stripe/browser_pay/pay.blade.php @@ -0,0 +1,39 @@ +@extends('portal.ninja2020.layout.payments', ['gateway_title' => ctrans('texts.browser_pay'), 'card_title' => ctrans('texts.browser_pay')]) + +@section('gateway_head') + @if($gateway->company_gateway->getConfigField('account_id')) + + + @else + + @endif + + + + +@endsection + +@section('gateway_content') +
+ @csrf + + + + + + +
+ + + + @include('portal.ninja2020.gateways.includes.payment_details') + + @component('portal.ninja2020.components.general.card-element-single') +
+ @endcomponent +@endsection + +@section('gateway_footer') + + +@endsection \ No newline at end of file diff --git a/webpack.mix.js b/webpack.mix.js index e593a4d750ae..f8c7b2ea7424 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -146,6 +146,10 @@ mix.js("resources/js/app.js", "public/js") "resources/js/clients/payments/stripe-przelewy24.js", "public/js/clients/payments/stripe-przelewy24.js" ) + .js( + "resources/js/clients/payments/stripe-browserpay.js", + "public/js/clients/payments/stripe-browserpay.js" + ) mix.copyDirectory('node_modules/card-js/card-js.min.css', 'public/css/card-js.min.css');