Source of file BraintreePageController.php
Size: 9,521 Bytes - Last Modified: 2022-02-21T10:01:05+00:00
/var/www/docs.ssmods.com/process/src/src/BraintreePageController.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 | <?php namespace AlexT\BTPayment; use Braintree_TransactionSearch; use PageController; use SilverStripe\Control\Controller; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\FormAction; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldConfig; use SilverStripe\Forms\GridField\GridFieldDataColumns; use SilverStripe\Forms\GridField\GridFieldPaginator; use SilverStripe\Forms\GridField\GridFieldSortableHeader; use SilverStripe\Forms\GridField\GridFieldToolbarHeader; use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\RequiredFields; use SilverStripe\Forms\TextField; use SilverStripe\ORM\ArrayList; use SilverStripe\Security\Security; use SilverStripe\View\Requirements; /** * Class BraintreePageController * * Custom PageController to include css and script files for Braintree Payment Gateway * @package SilverStripe\Lessons */ class BraintreePageController extends PageController { /** * {@inheritdoc} */ private static $allowed_actions = [ 'BTPaymentForm', 'BTEditPaymentForm', 'BTPreviousTransactions' ]; /** * Initialize the page * * Include necessary css and script files for Braintree Payment Gateway */ protected function init() { parent::init(); Requirements::javascript("https://js.braintreegateway.com/web/dropin/1.9.4/js/dropin.min.js"); Requirements::javascript('alext/silverstripe-btpayment: client/js/btscripts.js'); } /** * Generate a SilverStripe form to host the Braintree Dropin UI * * @return Braintree payment form using Dropin UI */ public function BTPaymentForm($defaultValue = 0) { $gateway = BraintreeExtension::BTGateway(); $member = Security::getCurrentUser(); $form = Form::create( $this, __FUNCTION__, // amount input, <div> block to inject BT dropin UI, hidden field to store payment method nonce FieldList::create( TextField::create('bt-amount','TOTAL AMOUNT ($)') ->addExtraClass('js-bt-amount') ->setReadonly(true) ->setValue($defaultValue), LiteralField::create('', '<p><div id="bt-dropin" class="js-bt-dropin"></div>'), HiddenField::create('bt-payment_method_nonce', '') ->addExtraClass('js-bt-nonce') ), // Submit button FieldList::create( FormAction::create('makePayment','Make Payment') ->setUseButtonTag(true) ->addExtraClass('btn btn-default-color btn-sm js-bt-button-make-payment') ), // RequiredFields::create('Amount') ) ->addExtraClass('js-bt-payment-form') // add client token as data attribute ->setAttribute('data-client-token', BraintreeExtension::BTClientToken($gateway, $member)) ->disableSecurityToken(); // retrieve data from saved session (if has) //$data = $this->getRequest()->getSession()->get("FormData.{$form->getName()}.data"); //return $data ? $form->loadDataFrom($data) : $form; return $form; } /** * Hanle payment form when submitted * * @param $data Submitted data * @param $form Original form * @return \SilverStripe\Control\HTTPResponse */ public function makePayment($data, $form) { // save data to session $session = $this->getRequest()->getSession(); $session->set("FormData.{$form->getName()}.data", $data); // received amount number $amount = $data['bt-amount']; // and payment method nonce sent from client $nonce = $data['bt-payment_method_nonce']; $result = $this->processPayment($session, $form, $nonce, $amount); $this->redirectBack(); return $result; } /** * @param $session * @param $form * @param $nonce * @param $amount * @return \SilverStripe\Control\HTTPResponse */ public function processPayment($session, $form, $nonce, $amount) { $gateway = BraintreeExtension::BTGateway(); // make a transaction $result = $gateway->transaction()->sale([ 'amount' => $amount, 'paymentMethodNonce' => $nonce, 'options' => [ 'submitForSettlement' => true ] ]); if ($result->success || !is_null($result->transaction)) { // clear session if everything is fine $session->clear("FormData.{$form->getName()}.data"); $form->sessionMessage('A payment of ' . $amount . '$ has been made!', 'Success'); } else { // ERROR $errorString = ""; foreach ($result->errors->deepAll() as $error) { $errorString .= 'Error: ' . $error->code . ": " . $error->message . "\n"; } $form->sessionError('Unable to make a payment! ' . $errorString, 'Failure'); } return $result; } /** * Generate SilverStripe to host a Braintree Drop UI form * * @return Braintree form using Dropin UI but disable 'choose another way to pay' */ public function BTEditPaymentForm() { $gateway = BraintreeExtension::BTGateway(); $member = Security::getCurrentUser(); $form = Form::create( $this, __FUNCTION__, // <div> block to inject Braintree Drop UI, hidden field to store method nonce, hidden field to store how many payment methods in the vault FieldList::create( LiteralField::create('', '<div id="bted-dropin" class="js-bted-dropin"></div>'), HiddenField::create('bted-payment_method_nonce', '') ->addExtraClass('js-bted-nonce') ), // Buttont to remove existing payment method or add a new card info as a new payment method FieldList::create( FormAction::create('editPayment','...') ->setUseButtonTag(true) ->addExtraClass('btn btn-default-color btn-sm js-bt-button-edit-payment') ), // null ) ->addExtraClass('js-bted-payment-form') // client token as data attribute ->setAttribute('data-client-token', BraintreeExtension::BTClientToken($gateway, $member)); return $form; } /** * Handle edit payment methods form * * @param $data Submitted data * @param $form The original form * @return \SilverStripe\Control\HTTPResponse * @throws \SilverStripe\ORM\ValidationException */ public function editPayment($data, $form) { // received nonce and how many payment methods in the vault $nonce = $data['bted-payment_method_nonce']; // create a new payment method, prevent duplicate to get the method token $gateway = BraintreeExtension::BTGateway(); $member = Security::getCurrentUser(); /* // get list of payment method tokens $customer = $gateway->customer()->find(BraintreeExtension::BTClientId($gateway, $member)); foreach ($customer->paymentMethods as $method) { // $method->token } */ // re-create payment method, which won't duplicate with the existing one, just to get the payment method token $result = $gateway->paymentMethod()->create([ 'customerId' => BraintreeExtension::BTClientId($gateway, $member), 'paymentMethodNonce' => $nonce, 'options' => [ 'failOnDuplicatePaymentMethod' => true ] ]); // remove this payment method based on the token if ($result->success || !is_null($result->paymentMethod)) { $gateway->paymentMethod()->delete($result->paymentMethod->token); } return $this->redirectBack(); } /** * @return Form * @throws \SilverStripe\ORM\ValidationException */ public function BTPreviousTransactionsForm() { $gateway = BraintreeExtension::BTGateway(); $member = Security::getCurrentUser(); $collection = $gateway->transaction()->search([ Braintree_TransactionSearch::customerId()->is(BraintreeExtension::BTClientId($gateway, $member)), ]); $transactions = ArrayList::create(); foreach ($collection as $transaction) { $bttransaction = new BraintreeTransaction($transaction); $transactions->push($bttransaction); } // columns to display for transaction $dataColumns = new GridFieldDataColumns(); $dataColumns->setDisplayFields(array( 'Date' => 'Date', 'Amount' => 'Amount', 'Currency' => 'Currency', 'Type' => 'Type', 'Status' => 'Status', )); $config = GridFieldConfig::create(); $config->addComponent(new GridFieldToolbarHeader()) ->addComponent(new GridFieldSortableHeader()) ->addComponent(new GridFieldPaginator(10)) ->addComponent($dataColumns); $grid = new GridField('transactions', 'Previous Transactions', $transactions, $config); return new Form($this, __FUNCTION__, new FieldList($grid), new FieldList()); } } |