├── .gitignore
├── code
└── community
│ └── Stabilis
│ └── PaypalExpressRedirect
│ ├── Test
│ ├── Helper
│ │ └── Data.php
│ └── Model
│ │ └── Api
│ │ └── Nvp.php
│ ├── Helper
│ └── Data.php
│ ├── etc
│ └── config.xml
│ └── Model
│ └── Api
│ └── Nvp.php
├── composer.json
├── locale
├── en_US
│ └── Stabilis_PaypalExpressRedirect.csv
├── de_DE
│ └── Stabilis_PaypalExpressRedirect.csv
├── fr_FR
│ └── Stabilis_PaypalExpressRedirect.csv
└── es_ES
│ └── Stabilis_PaypalExpressRedirect.csv
├── modman
├── etc
└── modules
│ └── Stabilis_PaypalExpressRedirect.xml
├── .travis.yml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | nbproject/*
2 | /vendor/
3 |
--------------------------------------------------------------------------------
/code/community/Stabilis/PaypalExpressRedirect/Test/Helper/Data.php:
--------------------------------------------------------------------------------
1 | _helper = Mage::helper('stabilis_paypalexpressredirect');
10 | }
11 |
12 | public function testClassExists() {
13 | $this->assertNotNull($this->_helper);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stabilis/paypal-express-redirect",
3 | "description": "Some PayPal error conditions are recoverable. Enhance your store by letting your customers recover a failed check out.",
4 | "type": "project",
5 | "require-dev": {},
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "Luke Leber",
10 | "email": "lukeleber@gmail.com"
11 | }
12 | ],
13 | "minimum-stability": "stable",
14 | "require": {}
15 | }
16 |
--------------------------------------------------------------------------------
/locale/en_US/Stabilis_PaypalExpressRedirect.csv:
--------------------------------------------------------------------------------
1 | "PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.","PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again."
2 | "PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.","PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again."
3 |
--------------------------------------------------------------------------------
/locale/de_DE/Stabilis_PaypalExpressRedirect.csv:
--------------------------------------------------------------------------------
1 | "PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.","PayPal konnte Ihre Zahlung nicht verarbeiten. Bitte klicken Sie hier um eine andere Zahlungsart in Ihrem PayPal Konto zu wählen und es erneut zu versuchen."
2 | "PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.","PayPal hat festgestellt, dass die angegebene Lieferadresse nicht existiert. Bitte überprüfen Sie Ihre Lieferadresse und versuchen es erneut."
3 |
--------------------------------------------------------------------------------
/locale/fr_FR/Stabilis_PaypalExpressRedirect.csv:
--------------------------------------------------------------------------------
1 | "PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.","PayPal n'a pas pu traiter votre paiement en ce moment. Veuillez cliquer ici pour sélectionner un autre mode de paiement à partir de votre compte PayPal et réessayer."
2 | "PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.","PayPal a déterminé que l'adresse de livraison spécifiée n'existe pas. Veuillez vérifier votre adresse de livraison et réessayer."
3 |
--------------------------------------------------------------------------------
/locale/es_ES/Stabilis_PaypalExpressRedirect.csv:
--------------------------------------------------------------------------------
1 | "PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.","PayPal no pudo procesar su pago en este momento. Por favor, haga clic aquí para seleccionar un método de pago diferente de su cuenta de PayPal y vuelva a intentarlo."
2 | "PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.","PayPal ha determinado que la dirección de envío especificada no existe. Compruebe por favor su dirección del envío e intente otra vez."
3 |
--------------------------------------------------------------------------------
/modman:
--------------------------------------------------------------------------------
1 | code/community/Stabilis/PaypalExpressRedirect/Helper/Data.php app/code/community/Stabilis/PaypalExpressRedirect/Helper/Data.php
2 | code/community/Stabilis/PaypalExpressRedirect/Model/Api/Nvp.php app/code/community/Stabilis/PaypalExpressRedirect/Model/Api/Nvp.php
3 | code/community/Stabilis/PaypalExpressRedirect/etc/config.xml app/code/community/Stabilis/PaypalExpressRedirect/etc/config.xml
4 | code/community/Stabilis/PaypalExpressRedirect/Test/Helper/Data.php app/code/community/Stabilis/PaypalExpressRedirect/Test/Helper/Data.php
5 | code/community/Stabilis/PaypalExpressRedirect/Test/Model/Api/Nvp.php app/code/community/Stabilis/PaypalExpressRedirect/Test/Model/Api/Nvp.php
6 | etc/modules/Stabilis_PaypalExpressRedirect.xml app/etc/modules/Stabilis_PaypalExpressRedirect.xml
7 | locale/en_US/Stabilis_PaypalExpressRedirect.csv app/locale/en_US/Stabilis_PaypalExpressRedirect.csv
8 | locale/es_ES/Stabilis_PaypalExpressRedirect.csv app/locale/es_ES/Stabilis_PaypalExpressRedirect.csv
9 | locale/fr_FR/Stabilis_PaypalExpressRedirect.csv app/locale/fr_FR/Stabilis_PaypalExpressRedirect.csv
10 |
--------------------------------------------------------------------------------
/etc/modules/Stabilis_PaypalExpressRedirect.xml:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 |
30 |
31 | true
32 | community
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | # There are issues with Magento 1.7.0.2 and MySQL 5.6+
4 | # So just uninstall mysql and install percona server 5.5.
5 | before_install:
6 | - sudo apt-get purge mysql-* -y
7 | - sudo rm -rf /etc/mysql /var/lib/mysql
8 | - sudo apt-get autoremove -y
9 | - sudo apt-get autoclean -y
10 | - sudo wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
11 | - sudo dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb
12 | - sudo apt-get update -y
13 | - sudo apt-get install percona-server-server-5.5 -y
14 |
15 | # Run all tests on php 5.3, 5.4, and 5.5
16 | php:
17 | - 5.4
18 | - 5.5
19 |
20 | # Run all tests on 1.7.0.2, 1.8.1.0, and 1.9.2.2
21 | # Pulled from mirrors since Magento Commerce links don't work anymore.
22 | env:
23 | - MAGENTO_VERSION=magento-mirror-1.7.0.2
24 | - MAGENTO_VERSION=magento-mirror-1.8.1.0
25 | - MAGENTO_VERSION=magento-mirror-1.9.2.2
26 |
27 | # php 5.3 requires ubuntu 12.04
28 | matrix:
29 | include:
30 | - php: 5.3
31 | dist: precise
32 | env: MAGENTO_VERSION=magento-mirror-1.7.0.2
33 | - php: 5.3
34 | dist: precise
35 | env: MAGENTO_VERSION=magento-mirror-1.8.1.0
36 | - php: 5.3
37 | dist: precise
38 | env: MAGENTO_VERSION=magento-mirror-1.9.2.2
39 |
40 |
41 | # Finally, install the MageTestStand framework to get things rolling.
42 | script:
43 | - curl -sSL https://raw.githubusercontent.com/LukeLeber/MageTestStand/master/setup.sh | bash
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/thinklikeamage/Stabilis_PaypalExpressRedirect)
2 |
3 |  Notice: PayPal has declared that the SOAP/NVP integration method is Deprecated as of January 1, 2017. Please review their New Integrations Guide.
4 |
5 | This extension will continue to function as expected until PayPal discontinues support for the SOAP/NVP integration method. At such a time, this documentation will be updated to reflect this.
6 | # Some PayPal error conditions are recoverable.
7 | ## Enhance your store by letting your customers recover a failed check out.
8 |
9 |
10 | This module intercepts several recoverable errors resulting from a failed PayPal Express checkout failure and redirects the user back to PayPal in accordance with the PayPal Documentation.
11 |
12 | -  Warning: It is HIGHLY RECOMMENDED to install any new extensions on a staging domain in order to test for conflicts.
13 | -  It is also HIGHLY RECOMMENDED to utilize a variety of source control management software (such as git).
14 | -  This module overrides `app/code/core/Mage/Paypal/Api/Nvp.php`.
15 | -  Never modify these files directly. If you need to override something, use the local code pool.
16 |
--------------------------------------------------------------------------------
/code/community/Stabilis/PaypalExpressRedirect/Helper/Data.php:
--------------------------------------------------------------------------------
1 | getFrontController()
42 | ->getResponse()
43 | ->setRedirect(
44 | Mage::getUrl('paypal/express/edit'),
45 | Stabilis_PaypalExpressRedirect_Model_Api_Nvp::HTTP_TEMPORARY_REDIRECT
46 | )
47 | ->sendResponse();
48 | exit;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/code/community/Stabilis/PaypalExpressRedirect/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 |
30 |
31 | 1.0.0
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Stabilis_PaypalExpressRedirect.csv
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Stabilis_PaypalExpressRedirect_Helper
49 |
50 |
51 |
52 |
53 | Stabilis_PaypalExpressRedirect_Model
54 |
55 |
56 |
57 | Stabilis_PaypalExpressRedirect_Model_Api_Nvp
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/code/community/Stabilis/PaypalExpressRedirect/Test/Model/Api/Nvp.php:
--------------------------------------------------------------------------------
1 | version = str_replace('magento-mirror-', '', getenv('MAGENTO_VERSION'));
40 |
41 | // Internally the core/session model is used (somewhere).
42 | // So we'll have to replace it with a mock.
43 | $this->replaceByMock(
44 | 'singleton',
45 | 'core/session',
46 | $this->getMockBuilder('Mage_Core_Model_Session')
47 | ->setMethods(array('start'))
48 | ->getMock()
49 | );
50 |
51 | // Instantiate the model under test.
52 | $this->_model = Mage::getModel('stabilis_paypalexpressredirect/api_nvp');
53 |
54 | // Some things from the model must be reflected to be accessed.
55 | $this->_modelClass = new ReflectionClass(get_class($this->_model));
56 |
57 | // We'll need to monitor observers.
58 | Mage::app()->enableEvents();
59 | }
60 |
61 | /**
62 | * Extracts the _requiredResponseParams property from the model under test.
63 | *
64 | * @return array
65 | */
66 | protected function getRequiredResponseParams() {
67 | $property = $this->_modelClass->getProperty('_requiredResponseParams');
68 | $property->setAccessible(true);
69 | return $property->getValue($this->_model);
70 | }
71 |
72 | /**
73 | * Extracts the DO_EXPRESS_CHECKOUT_PAYMENT from the model under test.
74 | *
75 | * @return string
76 | */
77 | protected function getDoExpressCheckoutPaymentString() {
78 | return $this->_modelClass->getConstant('DO_EXPRESS_CHECKOUT_PAYMENT');
79 | }
80 |
81 | /**
82 | * Tests the model default constructor.
83 | *
84 | * On Magento 1.9+, a required parameter is removed from the _requiredResponseParams property.
85 | *
86 | * On versions prior to 1.9, there are no parameter requirements imposed that must be adjusted.
87 | */
88 | public function testConstructor() {
89 |
90 | $requiredResponseParams = $this->getRequiredResponseParams();
91 |
92 | $doExpressCheckoutPaymentString = $this->getDoExpressCheckoutPaymentString();
93 |
94 | if(version_compare($this->version, '1.9', '>=')) {
95 |
96 | $this->assertArrayHasKey(
97 | $doExpressCheckoutPaymentString,
98 | $requiredResponseParams
99 | );
100 |
101 | $this->assertEquals(
102 | array('ACK', 'CORRELATIONID'),
103 | $requiredResponseParams[$doExpressCheckoutPaymentString]
104 | );
105 | } else {
106 |
107 | $this->assertArrayNotHasKey(
108 | $doExpressCheckoutPaymentString,
109 | $requiredResponseParams
110 | );
111 | }
112 | }
113 |
114 | /**
115 | * Extracts the _handleCallErrors method from the model under test.
116 | *
117 | * @return ReflectionMethod
118 | */
119 | protected function _getHandleCallErrorsMethod() {
120 | $className = get_class($this->_model);
121 | $class = new ReflectionClass($className);
122 | $method = $class->getMethod('_handleCallErrors');
123 | $method->setAccessible(true);
124 | return $method;
125 | }
126 |
127 | /**
128 | * Retrieves a limited, mock dataset that simulates a PayPal response.
129 | *
130 | * @return array
131 | */
132 | protected function _getFailureResponse($code) {
133 | return array(
134 | 'ACK' => 'Failure',
135 | 'L_ERRORCODE0' => $code,
136 | 'L_SHORTMESSAGE0' => 'Short Message',
137 | 'L_LONGMESSAGE0' => 'Long Message',
138 | 'L_SEVERITYCODE0' => ''
139 | );
140 | }
141 |
142 | /**
143 | * Asserts that at least one 'EVENT_EXPRESS_REDIRECT_TRIGGERED' event has been dispatched.
144 | */
145 | protected function assertEventFired() {
146 | $this->assertNotEquals(
147 | 0,
148 | Mage::app()->getDispatchedEventCount(
149 | $this->_modelClass->getConstant(
150 | 'EVENT_EXPRESS_REDIRECT_TRIGGERED'
151 | )
152 | )
153 | );
154 | }
155 |
156 | /**
157 | * Asserts that no 'EVENT_EXPRESS_REDIRECT_TRIGGERED' event has been fired.
158 | */
159 | protected function assertEventNotFired() {
160 | $this->assertEquals(
161 | 0,
162 | Mage::app()->getDispatchedEventCount(
163 | $this->_modelClass->getConstant(
164 | 'EVENT_EXPRESS_REDIRECT_TRIGGERED'
165 | )
166 | )
167 | );
168 | }
169 |
170 | /**
171 | * Tests a response code that falls outside of the handled cases.
172 | *
173 | * The behavior must be the same as the Magento Core in cases such as this.
174 | *
175 | * On Magento 1.9+, a generic exception is thrown.
176 | * On versions prior to 1.9, the user is presented with the raw PayPal messages.
177 | */
178 | public function testUnsupportedResponse() {
179 |
180 | $expected = version_compare(Mage::getVersion(), '1.9', '>=') ?
181 | 'There was an error processing your order. Please contact us or try again later.' :
182 | 'PayPal gateway has rejected request. Long Message (#12345: Short Message).';
183 |
184 | try {
185 |
186 | $method = $this->_getHandleCallErrorsMethod();
187 |
188 | $method->invoke(
189 | $this->_model,
190 | $this->_getFailureResponse(12345)
191 | );
192 |
193 | // If execution gets here, the test failed.
194 | $this->assertTrue(false);
195 |
196 | } catch(Exception $e) {
197 | $this->assertEquals($expected, $e->getMessage());
198 | }
199 |
200 | $this->assertEventNotFired();
201 |
202 | }
203 |
204 | /**
205 | * Test case for a '10417' response.
206 | *
207 | * In this case, the user must be presented with a link to go back to PayPal and try again.
208 | */
209 | public function test10417Response() {
210 |
211 | $expected = sprintf(
212 | 'PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.',
213 | Mage::getUrl('paypal/express/edit')
214 | );
215 |
216 | try {
217 |
218 | $method = $this->_getHandleCallErrorsMethod();
219 |
220 | $method->invoke(
221 | $this->_model,
222 | $this->_getFailureResponse(10417)
223 | );
224 |
225 | // If execution gets here, the test failed.
226 | $this->assertTrue(false);
227 |
228 | } catch(Exception $e) {
229 | $this->assertEquals($expected, $e->getMessage());
230 | }
231 |
232 | $this->assertEventFired();
233 |
234 | }
235 |
236 | /**
237 | * Test case for a '10422' response.
238 | *
239 | * In this case, the user must be presented with a link to go back to PayPal and try again.
240 | */
241 | public function test10422Response() {
242 |
243 | $expected = sprintf(
244 | 'PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.',
245 | Mage::getUrl('paypal/express/edit')
246 | );
247 |
248 | try {
249 |
250 | $method = $this->_getHandleCallErrorsMethod();
251 |
252 | $method->invoke(
253 | $this->_model,
254 | $this->_getFailureResponse(10422)
255 | );
256 |
257 | // If execution gets here, the test failed.
258 | $this->assertTrue(false);
259 |
260 | } catch(Exception $e) {
261 | $this->assertEquals($expected, $e->getMessage());
262 | }
263 |
264 | $this->assertEventFired();
265 |
266 | }
267 |
268 | /**
269 | * Test case for a '10736' response.
270 | *
271 | * In this case, the user is presented with a message explaining how to fix the situation.
272 | */
273 | public function test10736Response() {
274 |
275 | $expected = 'PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.';
276 |
277 | try {
278 |
279 | $method = $this->_getHandleCallErrorsMethod();
280 |
281 | $method->invoke(
282 | $this->_model,
283 | $this->_getFailureResponse(10736)
284 | );
285 |
286 | // If execution gets here, the test failed.
287 | $this->assertTrue(false);
288 |
289 | } catch(Exception $e) {
290 | $this->assertEquals($expected, $e->getMessage());
291 | }
292 |
293 | $this->assertEventFired();
294 |
295 | }
296 |
297 | /**
298 | * Test case for a '10486' response.
299 | *
300 | * I still have to do this one.
301 | */
302 | public function test10486Response() {
303 |
304 | $redirected = false;
305 |
306 | $mock = $this->getMock('Stabilis_PaypalExpressRedirect_Helper_Data');
307 |
308 | $mock->expects($this->once())
309 | ->method('redirectUser')
310 | ->will($this->returnCallback(function() use(&$redirected) {
311 | $redirected = true;
312 | }));
313 |
314 | // Ensure that the helper method doesn't actually terminate the process.
315 | $this->replaceByMock(
316 | 'helper',
317 | 'stabilis/paypalexpressredirect',
318 | $mock
319 | );
320 |
321 | $method = $this->_getHandleCallErrorsMethod();
322 |
323 | $method->invoke(
324 | $this->_model,
325 | $this->_getFailureResponse(10486)
326 | );
327 |
328 | $this->assertEventFired();
329 | $this->assertTrue($redirected);
330 | }
331 |
332 | }
333 |
--------------------------------------------------------------------------------
/code/community/Stabilis/PaypalExpressRedirect/Model/Api/Nvp.php:
--------------------------------------------------------------------------------
1 | =')) {
111 | $this->_requiredResponseParams[static::DO_EXPRESS_CHECKOUT_PAYMENT] = array('ACK', 'CORRELATIONID');
112 | }
113 |
114 | $this->_errors = array(
115 | static::API_UNABLE_TRANSACTION_COMPLETE => 'https://developer.paypal.com/docs/classic/express-checkout/ht_ec_fundingfailure10486',
116 | static::API_UNABLE_PROCESS_PAYMENT => 'https://www.paypal-knowledge.com/infocenter/index?page=content&id=FAQ1375&actp=LIST',
117 | static::API_DO_EXPRESS_CHECKOUT_FAIL => 'https://www.paypal-knowledge.com/infocenter/index?page=content&expand=true&locale=en_US&id=FAQ1850',
118 | static::API_BAD_SHIPPING_ADDRESS => 'https://www.paypal-knowledge.com/infocenter/index?page=content&id=FAQ2025&actp=LIST'
119 | );
120 | }
121 |
122 | /**
123 | * Throws an exception that is dependent upon the version of Magento.
124 | *
125 | * @param Exception $ex the exception to throw in Magento version <= 1.8
126 | *
127 | * @throws Exception
128 | */
129 | protected function _rethrow($ex) {
130 | if (version_compare(Mage::getVersion(), '1.9', '>=')) {
131 |
132 | // Preserve Magneto 1.9+ Behavior
133 | Mage::throwException(Mage::helper('paypal')
134 | ->__('There was an error processing your order. Please contact us or try again later.'));
135 | } else {
136 |
137 | // Preserve Magento <= 1.8 Behavior
138 | throw $ex;
139 | }
140 | }
141 |
142 | /**
143 | * Dispatches an event that third party code can handle.
144 | *
145 | * This event will fire when the user is redirected back to PayPal after payment failure.
146 | *
147 | * @param int $error the error condition that triggered the redirect
148 | *
149 | * @example
150 | *
151 | * class Third_Party_Model_Observer {
152 | *
153 | * public function onPayPalExpressRedirect(\Varien_Event_Observer $observer) {
154 | *
155 | * $errorCode = $observer->getEvent()->getErrorCode();
156 | *
157 | * // Custom logging?
158 | * // Perhaps send an email or SMS notification.
159 | * }
160 | * }
161 | *
162 | */
163 | protected function _dispatchRedirectEvent($error) {
164 |
165 | // Any data sent to the client prior to the redirect header could be detrimental.
166 | // So start collecting all output into a temporary buffer that will be later destroyed.
167 | //
168 | // Never trust third party code.
169 | ob_start();
170 |
171 | try {
172 |
173 | // Wrapped in a try-catch block, invoke any third party code that is listening
174 | Mage::dispatchEvent(
175 | static::EVENT_EXPRESS_REDIRECT_TRIGGERED,
176 | array(
177 | 'error_code' => $error,
178 | 'error_message' => $this->_errors[$error]
179 | )
180 | );
181 |
182 | } catch(Exception $thirdPartyException) {
183 |
184 | // Did the third party code throw an exception? Log it and continue.
185 | Mage::logException($thirdPartyException);
186 | }
187 |
188 | // Destroy the temporary output buffer
189 | ob_end_clean();
190 | }
191 |
192 | /**
193 | * Extends the functionality of the parent method by setting a redirect to
194 | * PayPal in the event of certain error conditions.
195 | *
196 | * @param array $response
197 | *
198 | * @throws Exception if an unrecoverable error exists within the response
199 | */
200 | protected function _handleCallErrors($response) {
201 | try {
202 |
203 | // Let the default functionality take its course
204 | parent::_handleCallErrors($response);
205 |
206 | } catch (Exception $ex) {
207 |
208 | // If there's more than one error, then there's no silver bullet.
209 | if(count($this->_callErrors) > 1) {
210 | $this->_rethrow($ex);
211 | }
212 |
213 | $error = $this->_callErrors[0];
214 |
215 | // If the error code is one we handle, dispatch an event.
216 | if(isset($this->_errors[$error])) {
217 | $this->_dispatchRedirectEvent($error);
218 | }
219 |
220 | switch($error) {
221 |
222 | // Redirect the user back to PayPal
223 | // TODO: Is there a better way to do this?
224 | case self::API_UNABLE_TRANSACTION_COMPLETE:
225 |
226 | Mage::helper('stabilis_paypalexpressredirect')->redirectUser();
227 |
228 | // Technically not required - although useful for being able to unit test this case.
229 | break;
230 |
231 | // Give the user an option to click a link to go back and
232 | // select another funding source
233 | case self::API_UNABLE_PROCESS_PAYMENT:
234 | case self::API_DO_EXPRESS_CHECKOUT_FAIL:
235 | Mage::throwException(Mage::helper('stabilis_paypalexpressredirect')
236 | ->__('PayPal could not process your payment at this time. Please click here to select a different payment method from within your PayPal account and try again.', Mage::getUrl('paypal/express/edit')));
237 |
238 | // The shipping address isn't right. Fix it on this page.
239 | case self::API_BAD_SHIPPING_ADDRESS:
240 | Mage::throwException(Mage::helper('stabilis_paypalexpressredirect')
241 | ->__('PayPal has determined that the specified shipping address does not exist. Please double-check your shipping address and try again.'));
242 |
243 | // Other error? Let the caller handle it.
244 | default:
245 | $this->_rethrow($ex);
246 | }
247 | }
248 | }
249 | }
250 |
--------------------------------------------------------------------------------