diff --git a/src/Message/RestAuthorizeRequest.php b/src/Message/RestAuthorizeRequest.php
index 2d61171..c75db20 100644
--- a/src/Message/RestAuthorizeRequest.php
+++ b/src/Message/RestAuthorizeRequest.php
@@ -15,7 +15,9 @@
* set to "authorize" (to authorize a payment to be captured later) rather than
* "sale" (which is used to capture a payment immediately).
*
- * Example:
+ * ### Example
+ *
+ * #### Initialize Gateway
*
*
* // Create a gateway for the PayPal RestGateway
@@ -28,7 +30,17 @@
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
+ *
+ *
+ * #### Direct Credit Card Authorize
*
+ * This is for the use case where a customer has presented their
+ * credit card details and you intend to use the PayPal REST gateway
+ * for processing a transaction using that credit card data.
+ *
+ * This does not require the customer to have a PayPal account.
+ *
+ *
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
@@ -66,6 +78,135 @@
* As of January 2015 these transactions are only supported in the UK
* and in the USA.
*
+ * #### PayPal Account Authorization
+ *
+ * This is for the use case where the customer intends to pay using their
+ * PayPal account. Note that no credit card details are provided, instead
+ * both a return URL and a cancel URL are required.
+ *
+ * The optimal solution here is to provide a unique return URL and cancel
+ * URL per transaction. That way your code will know what transaction is
+ * being returned or cancelled by PayPal.
+ *
+ * So step 1 is to store some transaction data somewhere on your system so
+ * that you have an ID when your transaction returns. How you do this of
+ * course depends on what framework, database layer, etc, you are using but
+ * for this step let's assume that you have a class set up that can save
+ * a transaction and return the object, and that you can retrieve the ID
+ * of that saved object using some call like getId() on the object. Most
+ * ORMs such as Doctrine ORM, Propel or Eloquent will have some methods
+ * that will allow you to do this or something similar.
+ *
+ *
+ * $transaction = MyClass::saveTransaction($some_data);
+ * $txn_id = $transaction->getId();
+ *
+ *
+ * Step 2 is to send the purchase request.
+ *
+ *
+ * // Do a purchase transaction on the gateway
+ * try {
+ * $transaction = $gateway->authorize(array(
+ * 'amount' => '10.00',
+ * 'currency' => 'AUD',
+ * 'description' => 'This is a test authorize transaction.',
+ * 'returnUrl' => 'http://mysite.com/paypal/return/?txn_id=' . $txn_id,
+ * 'cancelUrl' => 'http://mysite.com/paypal/return/?txn_id=' . $txn_id,
+ * ));
+ * $response = $transaction->send();
+ * $data = $response->getData();
+ * echo "Gateway purchase response data == " . print_r($data, true) . "\n";
+ *
+ * if ($response->isSuccessful()) {
+ * echo "Step 2 was successful!\n";
+ * }
+ *
+ * } catch (\Exception $e) {
+ * echo "Exception caught while attempting authorize.\n";
+ * echo "Exception type == " . get_class($e) . "\n";
+ * echo "Message == " . $e->getMessage() . "\n";
+ * }
+ *
+ *
+ * Step 3 is where your code needs to redirect the customer to the PayPal
+ * gateway so that the customer can sign in to their PayPal account and
+ * agree to authorize the payment. The response will implement an interface
+ * called RedirectResponseInterface from which the redirect URL can be obtained.
+ *
+ * How you do this redirect is up to your platform, code or framework at
+ * this point. For the below example I will assume that there is a
+ * function called redirectTo() which can handle it for you.
+ *
+ *
+ * if ($response->isRedirect()) {
+ * // Redirect the customer to PayPal so that they can sign in and
+ * // authorize the payment.
+ * echo "The transaction is a redirect";
+ * redirectTo($response->getRedirectUrl());
+ * }
+ *
+ *
+ * Step 4 is where the customer returns to your site. This will happen on
+ * either the returnUrl or the cancelUrl, that you provided in the purchase()
+ * call.
+ *
+ * If the cancelUrl is called then you can assume that the customer has not
+ * authorized the payment, therefore you can cancel the transaction.
+ *
+ * If the returnUrl is called, then you need to complete the transaction via
+ * a further call to PayPal.
+ *
+ * Note this example assumes that the authorize has been successful.
+ *
+ * The payer ID and the payment ID returned from the callback after the authorize
+ * will be passed to the return URL as GET parameters payerId and paymentId
+ * respectively.
+ *
+ *
+ * $paymentId = $_GET['paymentId'];
+ * $payerId = $_GET['payerId'];
+ *
+ * // Once the transaction has been approved, we need to complete it.
+ * $transaction = $gateway->completePurchase(array(
+ * 'payer_id' => $payer_id,
+ * 'transactionReference' => $sale_id,
+ * ));
+ * $response = $transaction->send();
+ * if ($response->isSuccessful()) {
+ * // The customer has successfully paid.
+ * echo "Step 4 was successful!\n";
+ * } else {
+ * // There was an error returned by completePurchase(). You should
+ * // check the error code and message from PayPal, which may be something
+ * // like "card declined", etc.
+ * }
+ *
+ *
+ * #### Note on Handling Error Messages
+ *
+ * PayPal account payments are a 2 step process. Firstly the customer needs to
+ * authorize the payment from PayPal to your application. Secondly, assuming that
+ * the customer does not have enough balance to pay the invoice from their PayPal
+ * balance, PayPal needs to transfer the funds from the customer's credit card to
+ * their PayPal account. This transaction is between PayPal and the customer, and
+ * not between the customer and you.
+ *
+ * If the second transaction fails then a call to completePurchase() will return
+ * an error. However this error message will be fairly generic. For privacy
+ * reasons, PayPal will not disclose to the merchant the full reason for the
+ * failure, they will only disclose this to the customer.
+ *
+ * Therefore on a failed completeAuthorize() call you could display an error message
+ * like this one:
+ *
+ * "PayPal failed to process the transaction from your card. For privacy reasons,
+ * PayPal are unable to disclose to us the reason for this failure. You should try
+ * a different payment method, a different card within PayPal, or contact PayPal
+ * support if you need to understand the reason for the failed transaction. PayPal
+ * may advise you to use a different card if the particular card is rejected
+ * by the card issuer."
+ *
* @link https://developer.paypal.com/docs/integration/direct/capture-payment/#authorize-the-payment
* @link https://developer.paypal.com/docs/api/#authorizations
* @link http://bit.ly/1wUQ33R
diff --git a/src/Message/RestCaptureRequest.php b/src/Message/RestCaptureRequest.php
index 98bc7b2..7db7e38 100644
--- a/src/Message/RestCaptureRequest.php
+++ b/src/Message/RestCaptureRequest.php
@@ -18,7 +18,9 @@
* indicate a final capture (prevent future captures) by setting the is_final_capture
* value to true.
*
- * Example -- note this example assumes that the authorization has been successful
+ * ### Example
+ *
+ * Note this example assumes that the authorization has been successful
* and that the authorization ID returned from the authorization is held in $auth_id.
* See RestAuthorizeRequest for the first part of this example transaction:
*
diff --git a/src/Message/RestCompletePurchaseRequest.php b/src/Message/RestCompletePurchaseRequest.php
index b265ba2..b246fce 100644
--- a/src/Message/RestCompletePurchaseRequest.php
+++ b/src/Message/RestCompletePurchaseRequest.php
@@ -15,19 +15,31 @@
* This call only works after a buyer has approved the payment using the
* provided PayPal approval URL.
*
- * Example -- note this example assumes that the purchase has been successful
- * and that the payer ID returned from the callback after the purchase is held
- * in $payer_id, and that the transaction ID returned by the initial payment is
- * held in $sale_id
+ * ### Example
+ *
+ * The payer ID and the payment ID returned from the callback after the purchase
+ * will be passed to the return URL as GET parameters payerId and paymentId
+ * respectively.
+ *
* See RestPurchaseRequest for the first part of this example transaction:
*
*
+ * $paymentId = $_GET['paymentId'];
+ * $payerId = $_GET['payerId'];
+ *
* // Once the transaction has been approved, we need to complete it.
* $transaction = $gateway->completePurchase(array(
* 'payer_id' => $payer_id,
* 'transactionReference' => $sale_id,
* ));
* $response = $transaction->send();
+ * if ($response->isSuccessful()) {
+ * // The customer has successfully paid.
+ * } else {
+ * // There was an error returned by completePurchase(). You should
+ * // check the error code and message from PayPal, which may be something
+ * // like "card declined", etc.
+ * }
*
*
* @see RestPurchaseRequest
diff --git a/src/Message/RestPurchaseRequest.php b/src/Message/RestPurchaseRequest.php
index f12446a..75b0100 100644
--- a/src/Message/RestPurchaseRequest.php
+++ b/src/Message/RestPurchaseRequest.php
@@ -19,7 +19,9 @@
* extending the RestAuthorizeRequest class and simply over-riding
* the getData() function to set the intent to sale.
*
- * Example:
+ * ### Example
+ *
+ * #### Initialize Gateway
*
*
* // Create a gateway for the PayPal RestGateway
@@ -32,7 +34,17 @@
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
+ *
+ *
+ * #### Direct Credit Card Payment
*
+ * This is for the use case where a customer has presented their
+ * credit card details and you intend to use the PayPal REST gateway
+ * for processing a transaction using that credit card data.
+ *
+ * This does not require the customer to have a PayPal account.
+ *
+ *
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
@@ -50,18 +62,25 @@
* 'billingState' => 'QLD',
* ));
*
- * // Do an authorisation transaction on the gateway
- * $transaction = $gateway->purchase(array(
- * 'amount' => '10.00',
- * 'currency' => 'AUD',
- * 'description' => 'This is a test purchase transaction.',
- * 'card' => $card,
- * ));
- * $response = $transaction->send();
- * if ($response->isSuccessful()) {
- * echo "Purchase transaction was successful!\n";
- * $sale_id = $response->getTransactionReference();
- * echo "Transaction reference = " . $sale_id . "\n";
+ * // Do a purchase transaction on the gateway
+ * try {
+ * $transaction = $gateway->purchase(array(
+ * 'amount' => '10.00',
+ * 'currency' => 'AUD',
+ * 'description' => 'This is a test purchase transaction.',
+ * 'card' => $card,
+ * ));
+ * $response = $transaction->send();
+ * $data = $response->getData();
+ * echo "Gateway purchase response data == " . print_r($data, true) . "\n";
+ *
+ * if ($response->isSuccessful()) {
+ * echo "Purchase transaction was successful!\n";
+ * }
+ * } catch (\Exception $e) {
+ * echo "Exception caught while attempting authorize.\n";
+ * echo "Exception type == " . get_class($e) . "\n";
+ * echo "Message == " . $e->getMessage() . "\n";
* }
*
*
@@ -70,6 +89,135 @@
* As of January 2015 these transactions are only supported in the UK
* and in the USA.
*
+ * #### PayPal Account Payment
+ *
+ * This is for the use case where the customer intends to pay using their
+ * PayPal account. Note that no credit card details are provided, instead
+ * both a return URL and a cancel URL are required.
+ *
+ * The optimal solution here is to provide a unique return URL and cancel
+ * URL per transaction. That way your code will know what transaction is
+ * being returned or cancelled by PayPal.
+ *
+ * So step 1 is to store some transaction data somewhere on your system so
+ * that you have an ID when your transaction returns. How you do this of
+ * course depends on what framework, database layer, etc, you are using but
+ * for this step let's assume that you have a class set up that can save
+ * a transaction and return the object, and that you can retrieve the ID
+ * of that saved object using some call like getId() on the object. Most
+ * ORMs such as Doctrine ORM, Propel or Eloquent will have some methods
+ * that will allow you to do this or something similar.
+ *
+ *
+ * $transaction = MyClass::saveTransaction($some_data);
+ * $txn_id = $transaction->getId();
+ *
+ *
+ * Step 2 is to send the purchase request.
+ *
+ *
+ * // Do a purchase transaction on the gateway
+ * try {
+ * $transaction = $gateway->purchase(array(
+ * 'amount' => '10.00',
+ * 'currency' => 'AUD',
+ * 'description' => 'This is a test purchase transaction.',
+ * 'returnUrl' => 'http://mysite.com/paypal/return/?txn_id=' . $txn_id,
+ * 'cancelUrl' => 'http://mysite.com/paypal/return/?txn_id=' . $txn_id,
+ * ));
+ * $response = $transaction->send();
+ * $data = $response->getData();
+ * echo "Gateway purchase response data == " . print_r($data, true) . "\n";
+ *
+ * if ($response->isSuccessful()) {
+ * echo "Step 2 was successful!\n";
+ * }
+ *
+ * } catch (\Exception $e) {
+ * echo "Exception caught while attempting purchase.\n";
+ * echo "Exception type == " . get_class($e) . "\n";
+ * echo "Message == " . $e->getMessage() . "\n";
+ * }
+ *
+ *
+ * Step 3 is where your code needs to redirect the customer to the PayPal
+ * gateway so that the customer can sign in to their PayPal account and
+ * agree to authorize the payment. The response will implement an interface
+ * called RedirectResponseInterface from which the redirect URL can be obtained.
+ *
+ * How you do this redirect is up to your platform, code or framework at
+ * this point. For the below example I will assume that there is a
+ * function called redirectTo() which can handle it for you.
+ *
+ *
+ * if ($response->isRedirect()) {
+ * // Redirect the customer to PayPal so that they can sign in and
+ * // authorize the payment.
+ * echo "The transaction is a redirect";
+ * redirectTo($response->getRedirectUrl());
+ * }
+ *
+ *
+ * Step 4 is where the customer returns to your site. This will happen on
+ * either the returnUrl or the cancelUrl, that you provided in the purchase()
+ * call.
+ *
+ * If the cancelUrl is called then you can assume that the customer has not
+ * authorized the payment, therefore you can cancel the transaction.
+ *
+ * If the returnUrl is called, then you need to complete the transaction via
+ * a further call to PayPal.
+ *
+ * Note this example assumes that the purchase has been successful.
+ *
+ * The payer ID and the payment ID returned from the callback after the purchase
+ * will be passed to the return URL as GET parameters payerId and paymentId
+ * respectively.
+ *
+ *
+ * $paymentId = $_GET['paymentId'];
+ * $payerId = $_GET['payerId'];
+ *
+ * // Once the transaction has been approved, we need to complete it.
+ * $transaction = $gateway->completePurchase(array(
+ * 'payer_id' => $payer_id,
+ * 'transactionReference' => $sale_id,
+ * ));
+ * $response = $transaction->send();
+ * if ($response->isSuccessful()) {
+ * // The customer has successfully paid.
+ * echo "Step 4 was successful!\n";
+ * } else {
+ * // There was an error returned by completePurchase(). You should
+ * // check the error code and message from PayPal, which may be something
+ * // like "card declined", etc.
+ * }
+ *
+ *
+ * #### Note on Handling Error Messages
+ *
+ * PayPal account payments are a 2 step process. Firstly the customer needs to
+ * authorize the payment from PayPal to your application. Secondly, assuming that
+ * the customer does not have enough balance to pay the invoice from their PayPal
+ * balance, PayPal needs to transfer the funds from the customer's credit card to
+ * their PayPal account. This transaction is between PayPal and the customer, and
+ * not between the customer and you.
+ *
+ * If the second transaction fails then a call to completePurchase() will return
+ * an error. However this error message will be fairly generic. For privacy
+ * reasons, PayPal will not disclose to the merchant the full reason for the
+ * failure, they will only disclose this to the customer.
+ *
+ * Therefore on a failed completePurchase() call you could display an error message
+ * like this one:
+ *
+ * "PayPal failed to process the transaction from your card. For privacy reasons,
+ * PayPal are unable to disclose to us the reason for this failure. You should try
+ * a different payment method, a different card within PayPal, or contact PayPal
+ * support if you need to understand the reason for the failed transaction. PayPal
+ * may advise you to use a different card if the particular card is rejected
+ * by the card issuer."
+ *
* @link https://developer.paypal.com/docs/api/#create-a-payment
* @see RestAuthorizeRequest
*/
diff --git a/src/RestGateway.php b/src/RestGateway.php
index ee89ff8..c202f91 100644
--- a/src/RestGateway.php
+++ b/src/RestGateway.php
@@ -24,6 +24,8 @@
* the Sandbox URIs. When you’re set to go live, use the live credentials assigned to
* your app to generate a new access token to be used with the live URIs.
*
+ * ### Test Mode
+ *
* In order to use this for testing in sandbox mode you will need at least two sandbox
* test accounts. One will need to be a business account, and one will need to be a
* personal account with credit card details. To create these yo will need to go to
@@ -46,13 +48,15 @@
* you need to do is provide the clientId and secret when you initialize the gateway,
* or use the set*() calls to set them after creating the gateway object.
*
+ * ### Credentials
+ *
* To create production and sandbox credentials for your PayPal account:
*
* * Log into your PayPal account.
* * Navigate to your Sandbox accounts at https://developer.paypal.com/webapps/developer/applications/accounts
* to ensure that you have a valid sandbox account to use for testing. If you don't already have a sandbox
* account, one can be created on this page. You will actually need 2 accounts, a personal account and a
- * business account, the business account is the one you need to use for creating API applications.
+ * business account, the business account is the one you need to use for creating API applications.
* * Check your account status on https://developer.paypal.com/webapps/developer/account/status to ensure
* that it is valid for live transactions.
* * Navigate to the My REST apps page: https://developer.paypal.com/webapps/developer/applications/myapps
@@ -68,7 +72,9 @@
* stored per app then it pays to have one API app per website that you are using (and an
* additional one for things like command line testing, etc).
*
- * Example:
+ * ### Example
+ *
+ * #### Initialize Gateway
*
*
* // Create a gateway for the PayPal RestGateway
@@ -81,7 +87,11 @@
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
+ *
*
+ * #### Direct Credit Card Payment
+ *
+ *
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
@@ -99,33 +109,30 @@
* 'billingState' => 'QLD',
* ));
*
- * // Do an authorisation transaction on the gateway
- * if ($gateway->supportsAuthorize()) {
- * try {
- * $transaction = $gateway->authorize(array(
- * 'amount' => '10.00',
- * 'currency' => 'AUD',
- * 'description' => 'This is a test authorize transaction.',
- * 'card' => $card,
- * ));
- * $response = $transaction->send();
- * $data = $response->getData();
- * echo "Gateway authorize response data == " . print_r($data, true) . "\n";
- *
- * if ($response->isSuccessful()) {
- * echo "Authorize transaction was successful!\n";
- * }
- * } catch (\Exception $e) {
- * echo "Exception caught while attempting authorize.\n";
- * echo "Exception type == " . get_class($e) . "\n";
- * echo "Message == " . $e->getMessage() . "\n";
+ * // Do a purchase transaction on the gateway
+ * try {
+ * $transaction = $gateway->purchase(array(
+ * 'amount' => '10.00',
+ * 'currency' => 'AUD',
+ * 'description' => 'This is a test purchase transaction.',
+ * 'card' => $card,
+ * ));
+ * $response = $transaction->send();
+ * $data = $response->getData();
+ * echo "Gateway purchase response data == " . print_r($data, true) . "\n";
+ *
+ * if ($response->isSuccessful()) {
+ * echo "Purchase transaction was successful!\n";
* }
- *
- * } else {
- * echo "Gateway does not support authorize.\n";
+ * } catch (\Exception $e) {
+ * echo "Exception caught while attempting authorize.\n";
+ * echo "Exception type == " . get_class($e) . "\n";
+ * echo "Message == " . $e->getMessage() . "\n";
* }
*
*
+ * ### Dashboard
+ *
* Once you have processed some payments you can go to the PayPal sandbox site,
* at https://www.sandbox.paypal.com/ and log in with the email address and password
* of your PayPal sandbox business test account. You will then see the result
@@ -182,7 +189,7 @@ public function getDefaultParameters()
/**
* Get OAuth 2.0 client ID for the access token.
- *
+ *
* Get an access token by using the OAuth 2.0 client_credentials
* token grant type with your clientId:secret as your Basic Auth
* credentials.
@@ -196,7 +203,7 @@ public function getClientId()
/**
* Set OAuth 2.0 client ID for the access token.
- *
+ *
* Get an access token by using the OAuth 2.0 client_credentials
* token grant type with your clientId:secret as your Basic Auth
* credentials.
@@ -211,7 +218,7 @@ public function setClientId($value)
/**
* Get OAuth 2.0 secret for the access token.
- *
+ *
* Get an access token by using the OAuth 2.0 client_credentials
* token grant type with your clientId:secret as your Basic Auth
* credentials.
@@ -225,7 +232,7 @@ public function getSecret()
/**
* Set OAuth 2.0 secret for the access token.
- *
+ *
* Get an access token by using the OAuth 2.0 client_credentials
* token grant type with your clientId:secret as your Basic Auth
* credentials.
@@ -272,7 +279,7 @@ public function createToken()
/**
* Set OAuth 2.0 access token.
- *
+ *
* @param string $value
* @return RestGateway provides a fluent interface
*/
@@ -283,7 +290,7 @@ public function setToken($value)
/**
* Get OAuth 2.0 access token expiry time.
- *
+ *
* @return integer
*/
public function getTokenExpires()
@@ -293,7 +300,7 @@ public function getTokenExpires()
/**
* Set OAuth 2.0 access token expiry time.
- *
+ *
* @param integer $value
* @return RestGateway provides a fluent interface
*/
@@ -503,7 +510,7 @@ public function refund(array $parameters = array())
* with PayPal instead of storing them on your own server. After storing
* a credit card, you can then pass the credit card id instead of the
* related credit card details to complete a payment.
- *
+ *
* @link https://developer.paypal.com/docs/api/#store-a-credit-card
* @param array $parameters
* @return \Omnipay\PayPal\Message\RestCreateCardRequest
@@ -519,7 +526,7 @@ public function createCard(array $parameters = array())
* Updating a card in the vault is no longer supported -- see
* http://stackoverflow.com/questions/20858910/paypal-rest-api-update-a-stored-credit-card
* Therefore the only way to update a card is to remove it using deleteCard and
- * then re-add it using createCard.
+ * then re-add it using createCard.
*
* @link https://developer.paypal.com/docs/api/#delete-a-stored-credit-card
* @param array $parameters