From e8982b2a698362c09cef09df6aac3197f8be0f62 Mon Sep 17 00:00:00 2001 From: David Valdez Date: Mon, 31 Aug 2015 16:23:07 -0700 Subject: [PATCH 1/5] Add functionality for sending requests from XML --- lib/CybsSoapClient.php | 54 ++++++++++++++++++++++++++++++++++++++++- samples/AuthFromXml.php | 18 ++++++++++++++ samples/xml/auth.xml | 42 ++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 samples/AuthFromXml.php create mode 100644 samples/xml/auth.xml diff --git a/lib/CybsSoapClient.php b/lib/CybsSoapClient.php index 5572abb..e1723e5 100644 --- a/lib/CybsSoapClient.php +++ b/lib/CybsSoapClient.php @@ -9,6 +9,8 @@ */ class CybsSoapClient extends SoapClient { + const CLIENT_LIBRARY_VERSION = "CyberSource PHP 1.0.0"; + private $merchantId; private $transactionKey; @@ -104,6 +106,40 @@ public function getTransactionKey() return $this->transactionKey; } + public function simpleXmlToCybsRequest($simpleXml) { + + $vars = get_object_vars($simpleXml); + $request = new stdClass(); + foreach(array_keys($vars) as $key) { + $element = $vars[$key]; + if ($key == 'comment') { + continue; + } + if (is_string($element)) { + $request->$key = $element; + } else if (is_array($element)) { + $array = $element; + if ($key == "@attributes") { + // Each attribute in the '@attributes' array should + // instead be a property of the parent element. + // copyAttributes($simpleXml, $array); + foreach($array as $k => $value) { + $request->$k = $value; + } + } else { + $newArray = array(); + foreach($array as $k => $value) { + $newArray[$k] = $this->simpleXmlToCybsRequest($value); + } + $request->$key = $newArray; + } + } else if ($element instanceof SimpleXMLElement) { + $request->$key = $this->simpleXmlToCybsRequest($element); + } + } + return $request; + } + /** * Returns an object initialized with basic client information. * @@ -115,9 +151,25 @@ public function createRequest($merchantReferenceCode) $request = new stdClass(); $request->merchantID = $this->merchantId; $request->merchantReferenceCode = $merchantReferenceCode; - $request->clientLibrary = "CyberSource PHP 1.0.0"; + $request->clientLibrary = self::CLIENT_LIBRARY_VERSION; $request->clientLibraryVersion = phpversion(); $request->clientEnvironment = php_uname(); return $request; } + + /** + * Runs a transaction from an XML file + * + * @param string $filePath The path to the XML file + * @param string $merchantReferenceCode Desired reference code for the request + * @return stdClass An object representation of the transaction response. + */ + public function runTransactionFromXml($filePath, $merchantReferenceCode) + { + $request = $this->createRequest($merchantReferenceCode); + $xml = simplexml_load_string(file_get_contents($filePath)); + $xmlRequest = $this->simpleXmlToCybsRequest($xml); + $mergedRequest = (object) array_merge((array) $request, (array) $xmlRequest); + return $this->runTransaction($mergedRequest); + } } diff --git a/samples/AuthFromXml.php b/samples/AuthFromXml.php new file mode 100644 index 0000000..add9114 --- /dev/null +++ b/samples/AuthFromXml.php @@ -0,0 +1,18 @@ +runTransactionFromXml(__DIR__ . '/xml/auth.xml', $referenceCode); + +// This section will show all the reply fields. +print("\nRESPONSE: " . print_r($reply, true)); diff --git a/samples/xml/auth.xml b/samples/xml/auth.xml new file mode 100644 index 0000000..864f7ca --- /dev/null +++ b/samples/xml/auth.xml @@ -0,0 +1,42 @@ + + --> + your_merchant_reference_code + + John + Doe + 1295 Charleston Road + Mountain View + CA + 94043 + US + 650-965-6000 + nobody@cybersource.com + 10.7.7.7 + + + Jane + Doe + 100 Elm Street + San Mateo + CA + 94401 + US + + + 12.34 + + + 56.78 + + + USD + + + 4111111111111111 + 12 + 2020 + + + + From 1770b8fee3596878faf79e29a4cc5b92290daa02 Mon Sep 17 00:00:00 2001 From: David Valdez Date: Wed, 2 Sep 2015 14:50:44 -0700 Subject: [PATCH 2/5] Add CybsNameValuePairClient for flat name-value pair requests. Add support for sending requests from XML strings --- lib/CybsClient.php | 116 +++++++++++++++++++++++++++ lib/CybsNameValuePairClient.php | 37 +++++++++ lib/CybsSoapClient.php | 121 ++++++----------------------- lib/conf/cybs.ini | 5 +- samples/AuthFromNameValuePairs.php | 37 +++++++++ samples/AuthFromXml.php | 2 +- 6 files changed, 217 insertions(+), 101 deletions(-) create mode 100644 lib/CybsClient.php create mode 100644 lib/CybsNameValuePairClient.php create mode 100644 samples/AuthFromNameValuePairs.php diff --git a/lib/CybsClient.php b/lib/CybsClient.php new file mode 100644 index 0000000..f904e90 --- /dev/null +++ b/lib/CybsClient.php @@ -0,0 +1,116 @@ +merchantId = $properties['merchant_id']; + $this->transactionKey = $properties['transaction_key']; + + $nameSpace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; + + $soapUsername = new SoapVar( + $this->merchantId, + XSD_STRING, + NULL, + $nameSpace, + NULL, + $nameSpace + ); + + $soapPassword = new SoapVar( + $this->transactionKey, + XSD_STRING, + NULL, + $nameSpace, + NULL, + $nameSpace + ); + + $auth = new stdClass(); + $auth->Username = $soapUsername; + $auth->Password = $soapPassword; + + $soapAuth = new SoapVar( + $auth, + SOAP_ENC_OBJECT, + NULL, $nameSpace, + 'UsernameToken', + $nameSpace + ); + + $token = new stdClass(); + $token->UsernameToken = $soapAuth; + + $soapToken = new SoapVar( + $token, + SOAP_ENC_OBJECT, + NULL, + $nameSpace, + 'UsernameToken', + $nameSpace + ); + + $security =new SoapVar( + $soapToken, + SOAP_ENC_OBJECT, + NULL, + $nameSpace, + 'Security', + $nameSpace + ); + + $header = new SoapHeader($nameSpace, 'Security', $security, true); + $this->__setSoapHeaders(array($header)); + } + + /** + * @return string The client's merchant ID. + */ + public function getMerchantId() + { + return $this->merchantId; + } + + /** + * @return string The client's transaction key. + */ + public function getTransactionKey() + { + return $this->transactionKey; + } +} \ No newline at end of file diff --git a/lib/CybsNameValuePairClient.php b/lib/CybsNameValuePairClient.php new file mode 100644 index 0000000..0d70513 --- /dev/null +++ b/lib/CybsNameValuePairClient.php @@ -0,0 +1,37 @@ + $v) { + $nvpRequest .= ($k . "=" . $v ."\n"); + } + return parent::runTransaction($nvpRequest); + } +} diff --git a/lib/CybsSoapClient.php b/lib/CybsSoapClient.php index e1723e5..a150a04 100644 --- a/lib/CybsSoapClient.php +++ b/lib/CybsSoapClient.php @@ -1,109 +1,19 @@ merchantId = $properties['merchant_id']; - $this->transactionKey = $properties['transaction_key']; - - $nameSpace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; - - $soapUsername = new SoapVar( - $this->merchantId, - XSD_STRING, - NULL, - $nameSpace, - NULL, - $nameSpace - ); - - $soapPassword = new SoapVar( - $this->transactionKey, - XSD_STRING, - NULL, - $nameSpace, - NULL, - $nameSpace - ); - - $auth = new stdClass(); - $auth->Username = $soapUsername; - $auth->Password = $soapPassword; - - $soapAuth = new SoapVar( - $auth, - SOAP_ENC_OBJECT, - NULL, $nameSpace, - 'UsernameToken', - $nameSpace - ); - - $token = new stdClass(); - $token->UsernameToken = $soapAuth; - - $soapToken = new SoapVar( - $token, - SOAP_ENC_OBJECT, - NULL, - $nameSpace, - 'UsernameToken', - $nameSpace - ); - - $security =new SoapVar( - $soapToken, - SOAP_ENC_OBJECT, - NULL, - $nameSpace, - 'Security', - $nameSpace - ); - - $header = new SoapHeader($nameSpace, 'Security', $security, true); - $this->__setSoapHeaders(array($header)); - } - - /** - * @return string The client's merchant ID. - */ - public function getMerchantId() - { - return $this->merchantId; - } - - /** - * @return string The client's transaction key. - */ - public function getTransactionKey() - { - return $this->transactionKey; + parent::__construct($options, $properties); } public function simpleXmlToCybsRequest($simpleXml) { @@ -122,7 +32,6 @@ public function simpleXmlToCybsRequest($simpleXml) { if ($key == "@attributes") { // Each attribute in the '@attributes' array should // instead be a property of the parent element. - // copyAttributes($simpleXml, $array); foreach($array as $k => $value) { $request->$k = $value; } @@ -149,7 +58,7 @@ public function simpleXmlToCybsRequest($simpleXml) { public function createRequest($merchantReferenceCode) { $request = new stdClass(); - $request->merchantID = $this->merchantId; + $request->merchantID = $this->getMerchantId(); $request->merchantReferenceCode = $merchantReferenceCode; $request->clientLibrary = self::CLIENT_LIBRARY_VERSION; $request->clientLibraryVersion = phpversion(); @@ -158,18 +67,32 @@ public function createRequest($merchantReferenceCode) } /** - * Runs a transaction from an XML file + * Runs a transaction from an XML string * * @param string $filePath The path to the XML file * @param string $merchantReferenceCode Desired reference code for the request * @return stdClass An object representation of the transaction response. */ - public function runTransactionFromXml($filePath, $merchantReferenceCode) + public function runTransactionFromXml($xml, $merchantReferenceCode) { $request = $this->createRequest($merchantReferenceCode); - $xml = simplexml_load_string(file_get_contents($filePath)); - $xmlRequest = $this->simpleXmlToCybsRequest($xml); + $simpleXml = simplexml_load_string($xml); + $xmlRequest = $this->simpleXmlToCybsRequest($simpleXml); $mergedRequest = (object) array_merge((array) $request, (array) $xmlRequest); return $this->runTransaction($mergedRequest); } + + /** + * Runs a transaction from an XML file + * + * @param string $filePath The path to the XML file + * @param string $merchantReferenceCode Desired reference code for the request + * @return stdClass An object representation of the transaction response. + */ + public function runTransactionFromFile($filePath, $merchantReferenceCode) + { + $request = $this->createRequest($merchantReferenceCode); + $xml = file_get_contents($filePath); + return $this->runTransactionFromXml($xml, $merchantReferenceCode); + } } diff --git a/lib/conf/cybs.ini b/lib/conf/cybs.ini index 32c6dd9..68a5f8f 100644 --- a/lib/conf/cybs.ini +++ b/lib/conf/cybs.ini @@ -2,4 +2,7 @@ merchant_id = your_merchant_id transaction_key = "your_transaction_key" ; Modify the URL to point to either a live or test WSDL file with the desired API version. -wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.109.wsdl" \ No newline at end of file +wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.109.wsdl" + +; Modify the URL to point to either a live or test WSDL file with the desired API version for the name-value pairs transaction API. +nvp_wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_NVP_1.120.wsdl" \ No newline at end of file diff --git a/samples/AuthFromNameValuePairs.php b/samples/AuthFromNameValuePairs.php new file mode 100644 index 0000000..2882774 --- /dev/null +++ b/samples/AuthFromNameValuePairs.php @@ -0,0 +1,37 @@ +runTransaction($request); + +// This section will show all the reply fields. +print("\nRESPONSE:\n" . $reply); diff --git a/samples/AuthFromXml.php b/samples/AuthFromXml.php index add9114..ccbff1e 100644 --- a/samples/AuthFromXml.php +++ b/samples/AuthFromXml.php @@ -12,7 +12,7 @@ $referenceCode = 'your_merchant_reference_code'; $client = new CybsSoapClient(); -$reply = $client->runTransactionFromXml(__DIR__ . '/xml/auth.xml', $referenceCode); +$reply = $client->runTransactionFromFile(__DIR__ . '/xml/auth.xml', $referenceCode); // This section will show all the reply fields. print("\nRESPONSE: " . print_r($reply, true)); From 6409731b364b2ab7f8e1dde62a8be53b1c9a6c9e Mon Sep 17 00:00:00 2001 From: David Valdez Date: Wed, 2 Sep 2015 17:20:55 -0700 Subject: [PATCH 3/5] Update readme for NVP and XML support. Update code comments --- README.md | 38 ++++++++++++++++++++++++++++-- lib/CybsSoapClient.php | 13 +++++++--- samples/AuthFromNameValuePairs.php | 4 ++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a7fd062..67f565a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This is the PHP client for the [CyberSource SOAP Toolkit API](http://www.cyberso ##Installation -You can install the client either via [Composer](https://getcomposer.org/) or manually. Before installing, make sure to configure the merchant ID, transaction key, and the WSDL file URL in ````cybs.ini````. By default, the WSDL file for the client is for API version 1.109 (the latest when this package was created). Available WSDL file URLs can be browsed at the following locations: +You can install the client either via [Composer](https://getcomposer.org/) or manually. Before installing, make sure to configure the merchant ID, transaction key, and the appropriate WSDL file URL in ````cybs.ini````. By default, the WSDL file for the client is for API version 1.120 (the latest when this package was updated). Available WSDL file URLs can be browsed at the following locations: - [test](https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/) - [live](https://ics2ws.ic3.com/commerce/1.x/transactionProcessor/) @@ -40,7 +40,10 @@ require_once('/path/to/project/lib/CybsSoapClient.php'); ##Getting Started -The PHP client will generate the request message headers for you, and will contain the methods specified by the WSDL file. The main method you'll use is ````runTransaction()````. To run a transaction, you'll first need to construct a client to generate a request object, which you can populate with the necessary fields (see [documentation](http://www.cybersource.com/developers/integration_methods/simple_order_and_soap_toolkit_api/soap_api/html/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Intro.04.4.html) for sample requests). The object will be converted into XML, so the properties of the object will need to correspond to the correct XML format. +The PHP client will generate the request message headers for you, and will contain the methods specified by the WSDL file. + +###Creating a simple request +The main method you'll use is ````runTransaction()````. To run a transaction, you'll first need to construct a client to generate a request object, which you can populate with the necessary fields (see [documentation](http://www.cybersource.com/developers/integration_methods/simple_order_and_soap_toolkit_api/soap_api/html/wwhelp/wwhimpl/js/html/wwhelp.htm#href=Intro.04.4.html) for sample requests). The object will be converted into XML, so the properties of the object will need to correspond to the correct XML format. ```php $client = new CybsSoapClient(); @@ -57,6 +60,37 @@ $request->card = $card; $reply = $client->runTransaction($request); ``` +###Creating a request from XML +You can create a request from XML either in a file or from an XML string. The XML request format is described in the **Using XML** section [here](http://apps.cybersource.com/library/documentation/dev_guides/Simple_Order_API_Clients/Client_SDK_SO_API.pdf). Here's how to run a transaction from an XML file: + +```php +$referenceCode = 'your_merchant_reference_code'; +$client = new CybsSoapClient(); +$reply = $client->runTransactionFromFile('path/to/my.xml', $referenceCode); +``` + +Or, you can create your own XML string and use that instead: + +```php +$xml = ""; +// Populate $xml +$client = new CybsSoapClient(); +$client->runTransactionFromXml($xml); +``` + +###Using name-value pairs +In order to run transactions using name-value pairs, make sure to set the value for the WSDL for the NVP transaction processor in ````cybs.ini````. Then use the ````CybsNameValuePairClient```` as so: + +```php +$client = new CybsNameValuePairClient(); +$request = array(); +$request['ccAuthService_run'] = 'true'; +$request['merchantID'] = 'my_merchant_id'; +$request['merchantReferenceCode'] = $'my_reference_code'; +// Populate $request +$reply = $client->runTransaction($request); +``` + ##Running the Samples After configuring your merchant ID and transaction key in ````cybs.ini````, the samples in the ````samples```` directory can be run from the project root. For example: diff --git a/lib/CybsSoapClient.php b/lib/CybsSoapClient.php index a150a04..fce96e1 100644 --- a/lib/CybsSoapClient.php +++ b/lib/CybsSoapClient.php @@ -16,10 +16,17 @@ function __construct($options=array()) parent::__construct($options, $properties); } - public function simpleXmlToCybsRequest($simpleXml) { - + /** + * Returns a properly formatted request object from a SimpleXMLElement. + * + * @param SimpleXMLElement $simpleXml Representation of an XML structure + * @return stdClass A request with the data from the SimpleXMLElement. + */ + public function simpleXmlToCybsRequest($simpleXml) + { $vars = get_object_vars($simpleXml); $request = new stdClass(); + foreach(array_keys($vars) as $key) { $element = $vars[$key]; if ($key == 'comment') { @@ -83,7 +90,7 @@ public function runTransactionFromXml($xml, $merchantReferenceCode) } /** - * Runs a transaction from an XML file + * Runs a transaction from an XML file. * * @param string $filePath The path to the XML file * @param string $merchantReferenceCode Desired reference code for the request diff --git a/samples/AuthFromNameValuePairs.php b/samples/AuthFromNameValuePairs.php index 2882774..3de11e5 100644 --- a/samples/AuthFromNameValuePairs.php +++ b/samples/AuthFromNameValuePairs.php @@ -15,8 +15,8 @@ $request = array(); $request['ccAuthService_run'] = 'true'; -$request['merchantID'] = 'dvaldez'; -$request['merchantReferenceCode'] = 'MRC-14344'; +$request['merchantID'] = 'your_merchant_id'; +$request['merchantReferenceCode'] = $referenceCode; $request['billTo_firstName'] = 'Jane'; $request['billTo_lastName'] = 'Smith'; $request['billTo_street1'] = '1295 Charleston Road'; From fa6e1174dc64fabc6bead43610fcd1aefea92b3f Mon Sep 17 00:00:00 2001 From: David Valdez Date: Wed, 2 Sep 2015 18:26:56 -0700 Subject: [PATCH 4/5] Update cybs.ini with latest WSDL --- lib/conf/cybs.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/conf/cybs.ini b/lib/conf/cybs.ini index 68a5f8f..c84f068 100644 --- a/lib/conf/cybs.ini +++ b/lib/conf/cybs.ini @@ -2,7 +2,7 @@ merchant_id = your_merchant_id transaction_key = "your_transaction_key" ; Modify the URL to point to either a live or test WSDL file with the desired API version. -wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.109.wsdl" +wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.120.wsdl" ; Modify the URL to point to either a live or test WSDL file with the desired API version for the name-value pairs transaction API. -nvp_wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_NVP_1.120.wsdl" \ No newline at end of file +nvp_wsdl = "https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor/CyberSourceTransaction_NVP_1.120.wsdl" From 919a21e1396acf51589ab997098e11f1deeeb618 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 18 Sep 2015 23:50:12 -0700 Subject: [PATCH 5/5] Update name-value pair client to automatically include the merchant ID. Fix incorrect require_once file in AuthFromNameValuePairs.php. Update samples to wrap output in
 tags

---
 lib/CybsNameValuePairClient.php    | 3 +++
 samples/AuthFollowOnCapture.php    | 4 +++-
 samples/AuthFromNameValuePairs.php | 5 +++--
 samples/AuthFromXml.php            | 2 ++
 samples/Sale.php                   | 2 ++
 samples/Subscription.php           | 3 ++-
 6 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/lib/CybsNameValuePairClient.php b/lib/CybsNameValuePairClient.php
index 0d70513..c7ceeb3 100644
--- a/lib/CybsNameValuePairClient.php
+++ b/lib/CybsNameValuePairClient.php
@@ -28,6 +28,9 @@ public function runTransaction($request)
         if (!is_array($request)) {
             throw new Exception('Name-value pairs must be in array');
         }
+        if (!array_key_exists('merchantID', $request)) {
+            $request['merchantID'] = $this->getMerchantId();
+        }
         $nvpRequest = "";
         foreach($request as $k => $v) {
             $nvpRequest .= ($k . "=" . $v ."\n");
diff --git a/samples/AuthFollowOnCapture.php b/samples/AuthFollowOnCapture.php
index 0ae0537..fd81c8a 100644
--- a/samples/AuthFollowOnCapture.php
+++ b/samples/AuthFollowOnCapture.php
@@ -56,6 +56,7 @@
 $reply = $client->runTransaction($request);
 
 // This section will show all the reply fields.
+echo '
';
 print("\nAUTH RESPONSE: " . print_r($reply, true));
 
 if ($reply->decision != 'ACCEPT') {
@@ -76,4 +77,5 @@
 $captureReply = $client->runTransaction($captureRequest);
 
 // This section will show all the reply fields.
-print("\nCAPTRUE RESPONSE: " . print_r($captureReply, true));
+print("\nCAPTURE RESPONSE: " . print_r($captureReply, true));
+echo '
'; diff --git a/samples/AuthFromNameValuePairs.php b/samples/AuthFromNameValuePairs.php index 3de11e5..c6450d1 100644 --- a/samples/AuthFromNameValuePairs.php +++ b/samples/AuthFromNameValuePairs.php @@ -5,7 +5,7 @@ // Using Composer-generated autoload file. require __DIR__ . '/../vendor/autoload.php'; // Or, uncomment the line below if you're not using Composer autoloader. -// require_once(__DIR__ . '/../lib/CybsSoapClient.php'); +// require_once(__DIR__ . '/../lib/CybsNameValuePairClient.php'); // Before using this example, you can use your own reference code for the transaction. @@ -15,7 +15,6 @@ $request = array(); $request['ccAuthService_run'] = 'true'; -$request['merchantID'] = 'your_merchant_id'; $request['merchantReferenceCode'] = $referenceCode; $request['billTo_firstName'] = 'Jane'; $request['billTo_lastName'] = 'Smith'; @@ -34,4 +33,6 @@ $reply = $client->runTransaction($request); // This section will show all the reply fields. +echo '
';
 print("\nRESPONSE:\n" . $reply);
+echo '
'; diff --git a/samples/AuthFromXml.php b/samples/AuthFromXml.php index ccbff1e..717623b 100644 --- a/samples/AuthFromXml.php +++ b/samples/AuthFromXml.php @@ -15,4 +15,6 @@ $reply = $client->runTransactionFromFile(__DIR__ . '/xml/auth.xml', $referenceCode); // This section will show all the reply fields. +echo '
';
 print("\nRESPONSE: " . print_r($reply, true));
+echo '
'; diff --git a/samples/Sale.php b/samples/Sale.php index 481b539..5d92cc7 100644 --- a/samples/Sale.php +++ b/samples/Sale.php @@ -50,4 +50,6 @@ $reply = $client->runTransaction($request); // This section will show all the reply fields. +echo '
';
 print("\nRESPONSE: " . print_r($reply, true));
+echo '
'; diff --git a/samples/Subscription.php b/samples/Subscription.php index 25ac2be..185906f 100644 --- a/samples/Subscription.php +++ b/samples/Subscription.php @@ -54,13 +54,14 @@ $reply = $client->runTransaction($request); // This section will show all the reply fields. +echo '
';
 print("\nSUBSCRIPTION RESPONSE: " . print_r($reply, true));
 
 if ($reply->decision != 'ACCEPT') {
     print("\nFailed subscription request.\n");
-    return;
 }
 else
 {
     print("\n Subscription service request successful\n");
 }
+echo '
';