From 9a0d100195f8b27948efb1db8a3ac7454bcef312 Mon Sep 17 00:00:00 2001 From: Al Twohill Date: Wed, 13 Mar 2019 21:29:24 +1300 Subject: [PATCH] Update documentation Tidy formatting --- code/controller/PxPaymentController.php | 67 +++++---- code/model/PxPayment.php | 22 ++- composer.json | 6 +- readme.md | 178 ++++++++++++++++++------ tests/readme.md | 4 - 5 files changed, 194 insertions(+), 83 deletions(-) delete mode 100644 tests/readme.md diff --git a/code/controller/PxPaymentController.php b/code/controller/PxPaymentController.php index a5c5b18..3e30011 100644 --- a/code/controller/PxPaymentController.php +++ b/code/controller/PxPaymentController.php @@ -8,27 +8,24 @@ use SilverStripe\Control\Director; use SilverStripe\Core\Convert; use SilverStripe\Control\NestedController; +use SilverStripe\ORM\ValidationException; - -/** - * Created by PhpStorm. - * User: al - * Date: 4/03/15 - * Time: 2:05 PM - */ -class PxPaymentController extends Controller implements NestedController { +class PxPaymentController extends Controller implements NestedController +{ protected $parentController; protected $payment; protected $urlSegment; protected $successURL; protected $failURL; - public function __construct(Controller $parentController, - HTTPRequest $request, - PxPayment $payment = null, - $successURL = null, - $failURL = null) { + public function __construct( + Controller $parentController, + HTTPRequest $request, + PxPayment $payment = null, + $successURL = null, + $failURL = null + ) { parent::__construct(); $this->parentController = $parentController; $this->payment = $payment; @@ -43,25 +40,31 @@ public function __construct(Controller $parentController, 'handle_response', ); - public function Link($action = null) { + public function Link($action = null) + { return Controller::join_links($this->parentController->Link(), "/{$this->urlSegment}/$action"); } - public function absoluteURL($action = '') { + public function absoluteURL($action = '') + { return Director::absoluteURL($this->Link($action)); } /** * Implement controller nesting */ - public function getNestedController() { + public function getNestedController() + { return $this->parentController; } /* * Submits the data to Payment Express, then redirects the user based on the response + * + * @throws Exception */ - public function submit($request) { + public function submit() + { if (!$this->payment) { user_error("No payment data supplied"); } @@ -70,14 +73,15 @@ public function submit($request) { $xml .= "" . $this->config()->get('PxPayKey') . ""; $xml .= "" . $this->absoluteURL("handle-response") . ""; $xml .= "" . $this->absoluteURL("handle-response") . ""; - foreach (array('TxnType', - 'MerchantReference', - 'TxnData1', - 'TxnData2', - 'TxnData3', - 'EmailAddress', - 'AmountInput', - 'CurrencyInput' + foreach (array( + 'TxnType', + 'MerchantReference', + 'TxnData1', + 'TxnData2', + 'TxnData3', + 'EmailAddress', + 'AmountInput', + 'CurrencyInput' ) as $key) { $xml .= "<$key>" . Convert::raw2xml($this->payment->$key) . ""; } @@ -111,7 +115,8 @@ public function submit($request) { /* * Handles the response */ - public function handle_response($request) { + public function handle_response(HTTPRequest $request) + { $token = $request->getVar('result'); if ($token) { @@ -146,8 +151,12 @@ public function handle_response($request) { $this->redirect($this->successURL); } else { if ($response->Success == 1) { - $this->payment->TxnId = "{$response->TxnId}"; - $this->payment->write(); + try { + $this->payment->TxnId = "{$response->TxnId}"; + $this->payment->write(); + } catch (ValidationException $e) { + $this->redirect($this->failURL); + } $this->redirect($this->successURL); } else { @@ -164,4 +173,4 @@ public function handle_response($request) { } } -} \ No newline at end of file +} diff --git a/code/model/PxPayment.php b/code/model/PxPayment.php index def9a11..2f5901c 100644 --- a/code/model/PxPayment.php +++ b/code/model/PxPayment.php @@ -4,12 +4,30 @@ use SilverStripe\ORM\DataObject; -class PxPayment extends DataObject { +/** + * Class PxPayment + * @package Twohill\PXPay + * + * @property string $TxnType + * @property string $MerchantReference + * @property string $TxnId + * @property string $TxnData1 + * @property string $TxnData2 + * @property string $TxnData3 + * @property string $EmailAddress + * @property double $CurrencyInput + * @property boolean $Processed + * + */ +class PxPayment extends DataObject +{ private static $table_name = "PXPayment"; private static $singular_name = "Payment"; + private static $plural_name = "Payments"; + private static $db = [ 'TxnType' => 'Enum("Purchase, Auth", "Purchase")', 'MerchantReference' => 'Varchar(64)', @@ -37,4 +55,4 @@ class PxPayment extends DataObject { 'AmountInput', 'Processed', ]; -} \ No newline at end of file +} diff --git a/composer.json b/composer.json index 87b2057..ea5a8d4 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,11 @@ "issues": "https://github.com/twohill/silverstripe-pxpay/issues" }, "require": { - "twohill/silverstripe-nestedcontrollers": "dev-master" + "twohill/silverstripe-nestedcontrollers": "^2", + "ext-curl": "*", + "ext-simplexml": "*" }, "extra": { "installer-name": "pxpay" } -} \ No newline at end of file +} diff --git a/readme.md b/readme.md index 21bf141..c150d80 100644 --- a/readme.md +++ b/readme.md @@ -1,69 +1,155 @@ -# SilverStripe supported module skeleton +# silverstripe-pxpay -A useful skeleton to more easily create modules that conform to the [Module Standard] -(https://docs.silverstripe.org/en/3.2/developer_guides/extending/modules/#module-standard). - -This readme contains descriptions of the parts of this module base you should customise to meet you own module needs. -For example, the module name in the H1 above should be you own module name, and the description text you are reading now -is where you should provide a good short explanation of what your module does. - -Where possible we have included default text that can be included as is into your module and indicated in -other places where you need to customise it - -Below is a template of the sections of your readme.md you should ideally include to met the Module Standard -and help others make use of your modules. +A module that integrates your controller with Payment Express. ## Requirements - * SilverStripe ^3.1 - * Other module - * Other server requirement - * Etc + * SilverStripe ^4 + * php-curl + * php-simplexml + ## Installation -Add some installation instructions here, having a 1 line composer copy and paste is useful. -Here is a composer command to create a new module project. Ensure you read the ['publishing a module'] -(https://docs.silverstripe.org/en/developer_guides/extending/how_tos/publish_a_module/) guide update you module -composer.json to designate your code as a SilverStripe module. +Using composer ``` -composer create-project silverstripe-module/skeleton module-name +composer require twohill/silverstripe-pxpay ``` ## License -See [License](license.md) - -We have included a 3-clause BSD license you can use as a default. We advocate for the BSD license as -it is one of the most permissive and open licenses. +BSD 3-Clause "New" or "Revised" License. See [License](license.md) -Feel free to alter the [license.md](license.md) to suit if you wan tto use an alternative license. -You can use [choosealicense.com](http://choosealicense.com) to help pick a suitable license for your project. -## Documentation - * [Documentation readme](docs/en/readme.md) +## Example configuration -Add links into your docs/ folder here unless your module only requires minimal documentation -in that case, add here and remove the docs folder. You might use this as a quick table of content if you -mhave multiple documentation pages. - -## Example configuration (optional) -If your module makes use of the config API in SIlverStripe it's a good idea to provide an example config - here that will get the module working out of the box and expose the user to the possible configuration options. - -Provide a yaml code example where possible. +Configure your PxPayment details in a config yml file. You can specify different settings for `dev` or `live` modes. +A useful option for doing this is to use your sandbox credentials when in `dev` mode. ```yaml -Page: - config_option: true - another_config: - - item1 - - item2 +--- +Only: + environment: 'live' +--- +Twohill\PXPay\PxPaymentController: + PxPayURL: https://sec.paymentexpress.com/pxaccess/pxpay.aspx + PxPayUserId: MyUserID + PxPayKey: xxxxxx + +--- +Only: + environment: 'dev' +--- +Twohill\PXPay\PxPaymentController: + PxPayURL: https://sec.paymentexpress.com/pxaccess/pxpay.aspx + PxPayUserId: MyUserID_dev + PxPayKey: xxxxxx ``` +## Example usage + +Return the `PxPaymentController` as the result of a payment method + +```php + +class MyPageController extends PageController +{ + private static $allowed_actions = [ + 'thankyou', + 'pay_order', + 'unsuccessful', + ]; + + public function thankyou(HTTPRequest $request) + { + $content = ''; + if ($request->getSession()->get('OrderID')) { + $order = Order::get()->byID($request->getSession()->get('OrderID')); + + if ($order) { + + $payment = $order->Payment(); + + if ($payment && $payment->TxnId) { + if ($payment->Processed) { + $sendEmail = false; + } else { + $payment->Processed = true; + $payment->write(); + } + } else { + $this->redirect($this->Link('pay-order/submit')); + } + $content = $this->ThankYouForPayingContent; // From MyPage $db + } + + $request->getSession()->clear("OrderID"); + return $this->customise(new ArrayData([ + 'Content' => DBField::create_field('HTMLFragment', $content), + 'Form' => '' + ])); + } + return $this->redirect($this->Link()); + } + /** + * Process the payment + * + * @param HTTPRequest $request + * @return PxPaymentController + * @throws ValidationException + */ + public function pay_order(HTTPRequest $request) + { + + // Load the payment details somehow + $payment = null; + + if ($request->getSession()->get('OrderID')) { + + $order = Order::get()->byID($request->getSession()->get('OrderID')); + + if ($order) { + $payment = new PxPayment(); + $payment->TxnType = "Purchase"; + $payment->MerchantReference = $order->InvoiceNumber; + $payment->TxnData1 = $order->CompanyName; + $payment->TxnData2 = $order->Address; + $payment->TxnData3 = $order->City; + $payment->EmailAddress = $order->Contact()->Email; + $payment->AmountInput = $order->Total; + $payment->CurrencyInput = "NZD"; + $payment->InvoiceID = $order->ID; + $payment->write(); + } + } + } + return new PxPaymentController($this, $request, $payment, $this->Link("thankyou"), $this->Link("unsuccessful")); + } + + /** + * Action when payment is unsuccessful. + */ + public function unsuccessful(HTTPRequest $request) + { + if ($request->getSession()->get('OrderID')) { + $order = Order::get()->byID($request->getSession()->get('OrderID')); + if ($order) { + return $this->customise([ + 'Content' => DBField::create_field('HTMLFragment', $this->UnsuccessfulContent), + 'Form' => '' + ]); + } + } + return $this->redirect($this->Link()); + } + + +} + +``` + ## Maintainers - * Person here - * Another maintainer + * Al Twohill ## Bugtracker Bugs are tracked in the issues section of this repository. Before submitting an issue please read over diff --git a/tests/readme.md b/tests/readme.md deleted file mode 100644 index a58dc60..0000000 --- a/tests/readme.md +++ /dev/null @@ -1,4 +0,0 @@ -# Tests -Look over the [Testing documentation](https://docs.silverstripe.org/en/developer_guides/testing/) - -Make sure to remove this readme in your actual module! \ No newline at end of file