lockfile again

This commit is contained in:
Tim Bendt
2025-11-26 11:50:55 -05:00
parent af3c23cb6e
commit 6ceecaa69e
4461 changed files with 641349 additions and 10 deletions

View File

@@ -0,0 +1,356 @@
<?php
/**
* PayPal Abstract Request
*/
namespace Omnipay\PayPal\Message;
use Omnipay\Common\ItemBag;
use Omnipay\PayPal\PayPalItem;
use Omnipay\PayPal\PayPalItemBag;
/**
* PayPal Abstract Request
*
* This class forms the base class for PayPal Express Checkout and Pro Checkout
* requests. These are also known as "Payflow Gateway" requests and also
* "PayPal Classic APIs".
*
* According to the PayPal documentation:
*
* * This is the recommended way to integrate when you want to accept payments
* with a completely customizable solution. This integration method leverages
* the PayPal Payflow Gateway to transmit payments your PayPal Internet Merchant
* Account; it also gives the merchant the flexibility to change payment
* processors without having to re-do their technical integration. When using
* PayPal Payments Pro (Payflow Edition) using Payflow Gateway integration,
* merchants can use Transparent Redirect feature to help manage PCI compliance.
*
* @link https://developer.paypal.com/docs/classic/products/payflow-gateway/
* @link https://developer.paypal.com/docs/classic/express-checkout/gs_expresscheckout/
* @link https://developer.paypal.com/docs/classic/products/ppp-payflow-edition/
* @link https://devtools-paypal.com/integrationwizard/
* @link http://paypal.github.io/sdk/
*/
abstract class AbstractRequest extends \Omnipay\Common\Message\AbstractRequest
{
const API_VERSION = '119.0';
protected $liveEndpoint = 'https://api-3t.paypal.com/nvp';
protected $testEndpoint = 'https://api-3t.sandbox.paypal.com/nvp';
/**
* @var bool
*/
protected $negativeAmountAllowed = true;
public function getUsername()
{
return $this->getParameter('username');
}
public function setUsername($value)
{
return $this->setParameter('username', $value);
}
public function getPassword()
{
return $this->getParameter('password');
}
public function setPassword($value)
{
return $this->setParameter('password', $value);
}
public function getSignature()
{
return $this->getParameter('signature');
}
public function setSignature($value)
{
return $this->setParameter('signature', $value);
}
public function getSubject()
{
return $this->getParameter('subject');
}
public function setSubject($value)
{
return $this->setParameter('subject', $value);
}
public function getSolutionType()
{
return $this->getParameter('solutionType');
}
public function setSolutionType($value)
{
return $this->setParameter('solutionType', $value);
}
public function getLandingPage()
{
return $this->getParameter('landingPage');
}
public function setLandingPage($value)
{
return $this->setParameter('landingPage', $value);
}
public function getHeaderImageUrl()
{
return $this->getParameter('headerImageUrl');
}
public function setHeaderImageUrl($value)
{
return $this->setParameter('headerImageUrl', $value);
}
public function getLogoImageUrl()
{
return $this->getParameter('logoImageUrl');
}
public function setLogoImageUrl($value)
{
return $this->setParameter('logoImageUrl', $value);
}
public function getBorderColor()
{
return $this->getParameter('borderColor');
}
public function setBorderColor($value)
{
return $this->setParameter('borderColor', $value);
}
public function getBrandName()
{
return $this->getParameter('brandName');
}
public function setBrandName($value)
{
return $this->setParameter('brandName', $value);
}
public function getNoShipping()
{
return $this->getParameter('noShipping');
}
public function setNoShipping($value)
{
return $this->setParameter('noShipping', $value);
}
public function getAllowNote()
{
return $this->getParameter('allowNote');
}
public function setAllowNote($value)
{
return $this->setParameter('allowNote', $value);
}
public function getAddressOverride()
{
return $this->getParameter('addressOverride');
}
public function setAddressOverride($value)
{
return $this->setParameter('addressOverride', $value);
}
public function getMaxAmount()
{
return $this->getParameter('maxAmount');
}
public function setMaxAmount($value)
{
return $this->setParameter('maxAmount', $value);
}
public function getTaxAmount()
{
return $this->getParameter('taxAmount');
}
public function setTaxAmount($value)
{
return $this->setParameter('taxAmount', $value);
}
public function getShippingAmount()
{
return $this->getParameter('shippingAmount');
}
public function setShippingAmount($value)
{
return $this->setParameter('shippingAmount', $value);
}
public function getHandlingAmount()
{
return $this->getParameter('handlingAmount');
}
public function setHandlingAmount($value)
{
return $this->setParameter('handlingAmount', $value);
}
public function getShippingDiscount()
{
return $this->getParameter('shippingDiscount');
}
public function setShippingDiscount($value)
{
return $this->setParameter('shippingDiscount', $value);
}
public function getInsuranceAmount()
{
return $this->getParameter('insuranceAmount');
}
public function setInsuranceAmount($value)
{
return $this->setParameter('insuranceAmount', $value);
}
public function getLocaleCode()
{
return $this->getParameter('localeCode');
}
/*
* Used to change the locale of PayPal pages.
* Accepts 2 or 5 character language codes as described here:
* https://developer.paypal.com/docs/classic/express-checkout/integration-guide/ECCustomizing/
*
* If no value/invalid value is passed, the gateway will default it for you
*/
public function setLocaleCode($value)
{
return $this->setParameter('localeCode', $value);
}
public function setCustomerServiceNumber($value)
{
return $this->setParameter('customerServiceNumber', $value);
}
public function getCustomerServiceNumber()
{
return $this->getParameter('customerServiceNumber');
}
public function setSellerPaypalAccountId($value)
{
return $this->setParameter('sellerPaypalAccountId', $value);
}
public function getSellerPaypalAccountId()
{
return $this->getParameter('sellerPaypalAccountId');
}
/**
* The Button Source (BN Code) is for PayPal Partners taking payments for a 3rd party
*/
public function setButtonSource($value)
{
return $this->setParameter('ButtonSource', $value);
}
public function getButtonSource()
{
return $this->getParameter('ButtonSource');
}
protected function getBaseData()
{
$data = array();
$data['VERSION'] = static::API_VERSION;
$data['USER'] = $this->getUsername();
$data['PWD'] = $this->getPassword();
$data['SIGNATURE'] = $this->getSignature();
$data['SUBJECT'] = $this->getSubject();
$bnCode = $this->getButtonSource();
if (!empty($bnCode)) {
$data['BUTTONSOURCE'] = $bnCode;
}
return $data;
}
protected function getItemData()
{
$data = array();
$items = $this->getItems();
if ($items) {
$data["PAYMENTREQUEST_0_ITEMAMT"] = 0;
foreach ($items as $n => $item) {
$data["L_PAYMENTREQUEST_0_NAME$n"] = $item->getName();
$data["L_PAYMENTREQUEST_0_DESC$n"] = $item->getDescription();
$data["L_PAYMENTREQUEST_0_QTY$n"] = $item->getQuantity();
$data["L_PAYMENTREQUEST_0_AMT$n"] = $this->formatCurrency($item->getPrice());
if ($item instanceof PayPalItem) {
$data["L_PAYMENTREQUEST_0_NUMBER$n"] = $item->getCode();
}
$data["PAYMENTREQUEST_0_ITEMAMT"] += $item->getQuantity() * $this->formatCurrency($item->getPrice());
}
$data["PAYMENTREQUEST_0_ITEMAMT"] = $this->formatCurrency($data["PAYMENTREQUEST_0_ITEMAMT"]);
}
return $data;
}
public function sendData($data)
{
$httpResponse = $this->httpClient->request('POST', $this->getEndpoint(), [], http_build_query($data, '', '&'));
return $this->createResponse($httpResponse->getBody()->getContents());
}
protected function getEndpoint()
{
return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
}
protected function createResponse($data)
{
return $this->response = new Response($this, $data);
}
/**
* Set the items in this order
*
* @param ItemBag|array $items An array of items in this order
*/
public function setItems($items)
{
if ($items && !$items instanceof ItemBag) {
$items = new PayPalItemBag($items);
}
return $this->setParameter('items', $items);
}
}

View File

@@ -0,0 +1,189 @@
<?php
/**
* PayPal Abstract REST Request
*/
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Exception\InvalidResponseException;
/**
* PayPal Abstract REST Request
*
* This class forms the base class for PayPal REST requests via the PayPal REST APIs.
*
* A complete REST operation is formed by combining an HTTP method (or “verb”) with
* the full URI to the resource youre addressing. For example, here is the operation
* to create a new payment:
*
* <code>
* POST https://api.paypal.com/v1/payments/payment
* </code>
*
* To create a complete request, combine the operation with the appropriate HTTP headers
* and any required JSON payload.
*
* @link https://developer.paypal.com/docs/api/
* @link https://devtools-paypal.com/integrationwizard/
* @link http://paypal.github.io/sdk/
* @see Omnipay\PayPal\RestGateway
*/
abstract class AbstractRestRequest extends \Omnipay\Common\Message\AbstractRequest
{
const API_VERSION = 'v1';
/**
* Sandbox Endpoint URL
*
* The PayPal REST APIs are supported in two environments. Use the Sandbox environment
* for testing purposes, then move to the live environment for production processing.
* When testing, generate an access token with your test credentials to make calls to
* the Sandbox URIs. When youre 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.
*
* @var string URL
*/
protected $testEndpoint = 'https://api.sandbox.paypal.com';
/**
* Live Endpoint URL
*
* When youre 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.
*
* @var string URL
*/
protected $liveEndpoint = 'https://api.paypal.com';
/**
* PayPal Payer ID
*
* @var string PayerID
*/
protected $payerId = null;
public function getClientId()
{
return $this->getParameter('clientId');
}
public function setClientId($value)
{
return $this->setParameter('clientId', $value);
}
public function getSecret()
{
return $this->getParameter('secret');
}
public function setSecret($value)
{
return $this->setParameter('secret', $value);
}
public function getToken()
{
return $this->getParameter('token');
}
public function setToken($value)
{
return $this->setParameter('token', $value);
}
public function getPayerId()
{
return $this->getParameter('payerId');
}
public function setPayerId($value)
{
return $this->setParameter('payerId', $value);
}
/**
* Get HTTP Method.
*
* This is nearly always POST but can be over-ridden in sub classes.
*
* @return string
*/
protected function getHttpMethod()
{
return 'POST';
}
protected function getEndpoint()
{
$base = $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
return $base . '/' . self::API_VERSION;
}
public function sendData($data)
{
// Guzzle HTTP Client createRequest does funny things when a GET request
// has attached data, so don't send the data if the method is GET.
if ($this->getHttpMethod() == 'GET') {
$requestUrl = $this->getEndpoint() . '?' . http_build_query($data);
$body = null;
} else {
$body = $this->toJSON($data);
$requestUrl = $this->getEndpoint();
}
// Might be useful to have some debug code here, PayPal especially can be
// a bit fussy about data formats and ordering. Perhaps hook to whatever
// logging engine is being used.
// echo "Data == " . json_encode($data) . "\n";
try {
$httpResponse = $this->httpClient->request(
$this->getHttpMethod(),
$this->getEndpoint(),
array(
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $this->getToken(),
'Content-type' => 'application/json',
),
$body
);
// Empty response body should be parsed also as and empty array
$body = (string) $httpResponse->getBody()->getContents();
$jsonToArrayResponse = !empty($body) ? json_decode($body, true) : array();
return $this->response = $this->createResponse($jsonToArrayResponse, $httpResponse->getStatusCode());
} catch (\Exception $e) {
throw new InvalidResponseException(
'Error communicating with payment gateway: ' . $e->getMessage(),
$e->getCode()
);
}
}
/**
* Returns object JSON representation required by PayPal.
* The PayPal REST API requires the use of JSON_UNESCAPED_SLASHES.
*
* Adapted from the official PayPal REST API PHP SDK.
* (https://github.com/paypal/PayPal-PHP-SDK/blob/master/lib/PayPal/Common/PayPalModel.php)
*
* @param int $options http://php.net/manual/en/json.constants.php
* @return string
*/
public function toJSON($data, $options = 0)
{
// Because of PHP Version 5.3, we cannot use JSON_UNESCAPED_SLASHES option
// Instead we would use the str_replace command for now.
// TODO: Replace this code with return json_encode($this->toArray(), $options | 64); once we support PHP >= 5.4
if (version_compare(phpversion(), '5.4.0', '>=') === true) {
return json_encode($data, $options | 64);
}
return str_replace('\\/', '/', json_encode($data, $options));
}
protected function createResponse($data, $statusCode)
{
return $this->response = new RestResponse($this, $data, $statusCode);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Capture Request
*/
class CaptureRequest extends AbstractRequest
{
public function getData()
{
$this->validate('transactionReference', 'amount');
$data = $this->getBaseData();
$data['METHOD'] = 'DoCapture';
$data['AMT'] = $this->getAmount();
$data['CURRENCYCODE'] = $this->getCurrency();
$data['AUTHORIZATIONID'] = $this->getTransactionReference();
$data['COMPLETETYPE'] = 'Complete';
return $data;
}
}

View File

@@ -0,0 +1,195 @@
<?php
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Exception\InvalidRequestException;
use Omnipay\PayPal\Support\InstantUpdateApi\ShippingOption;
use Omnipay\PayPal\Support\InstantUpdateApi\BillingAgreement;
/**
* PayPal Express Authorize Request
*/
class ExpressAuthorizeRequest extends AbstractRequest
{
const DEFAULT_CALLBACK_TIMEOUT = 5;
public function setCallback($callback)
{
return $this->setParameter('callback', $callback);
}
public function getCallback()
{
return $this->getParameter('callback');
}
public function setCallbackTimeout($callbackTimeout)
{
return $this->setParameter('callbackTimeout', $callbackTimeout);
}
public function getCallbackTimeout()
{
return $this->getParameter('callbackTimeout');
}
/**
* @param ShippingOption[] $data
*/
public function setShippingOptions($data)
{
$this->setParameter('shippingOptions', $data);
}
/**
* @return ShippingOption[]
*/
public function getShippingOptions()
{
return $this->getParameter('shippingOptions');
}
/**
* @param BillingAgreement $data
*/
public function setBillingAgreement($data)
{
$this->setParameter('billingAgreement', $data);
}
/**
* @return BillingAgreement
*/
public function getBillingAgreement()
{
return $this->getParameter('billingAgreement');
}
protected function validateCallback()
{
$callback = $this->getCallback();
if (!empty($callback)) {
$shippingOptions = $this->getShippingOptions();
if (empty($shippingOptions)) {
throw new InvalidRequestException(
'When setting a callback for the Instant Update API you must set shipping options'
);
} else {
$hasDefault = false;
foreach ($shippingOptions as $shippingOption) {
if ($shippingOption->isDefault()) {
$hasDefault = true;
continue;
}
}
if (!$hasDefault) {
throw new InvalidRequestException(
'One of the supplied shipping options must be set as default'
);
}
}
}
}
public function getData()
{
$this->validate('amount', 'returnUrl', 'cancelUrl');
$this->validateCallback();
$data = $this->getBaseData();
$data['METHOD'] = 'SetExpressCheckout';
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Authorization';
$data['PAYMENTREQUEST_0_AMT'] = $this->getAmount();
$data['PAYMENTREQUEST_0_CURRENCYCODE'] = $this->getCurrency();
$data['PAYMENTREQUEST_0_INVNUM'] = $this->getTransactionId();
$data['PAYMENTREQUEST_0_DESC'] = $this->getDescription();
// pp express specific fields
$data['SOLUTIONTYPE'] = $this->getSolutionType();
$data['LANDINGPAGE'] = $this->getLandingPage();
$data['RETURNURL'] = $this->getReturnUrl();
$data['CANCELURL'] = $this->getCancelUrl();
$data['HDRIMG'] = $this->getHeaderImageUrl();
$data['BRANDNAME'] = $this->getBrandName();
$data['NOSHIPPING'] = $this->getNoShipping();
$data['ALLOWNOTE'] = $this->getAllowNote();
$data['ADDROVERRIDE'] = $this->getAddressOverride();
$data['LOGOIMG'] = $this->getLogoImageUrl();
$data['CARTBORDERCOLOR'] = $this->getBorderColor();
$data['LOCALECODE'] = $this->getLocaleCode();
$data['CUSTOMERSERVICENUMBER'] = $this->getCustomerServiceNumber();
$callback = $this->getCallback();
if (!empty($callback)) {
$data['CALLBACK'] = $callback;
// callback timeout MUST be included and > 0
$timeout = $this->getCallbackTimeout();
$data['CALLBACKTIMEOUT'] = $timeout > 0 ? $timeout : self::DEFAULT_CALLBACK_TIMEOUT;
// if you're using a callback you MUST set shipping option(s)
$shippingOptions = $this->getShippingOptions();
if (!empty($shippingOptions)) {
foreach ($shippingOptions as $index => $shipping) {
$data['L_SHIPPINGOPTIONNAME' . $index] = $shipping->getName();
$data['L_SHIPPINGOPTIONAMOUNT' . $index] = number_format($shipping->getAmount(), 2);
$data['L_SHIPPINGOPTIONISDEFAULT' . $index] = $shipping->isDefault() ? '1' : '0';
if ($shipping->hasLabel()) {
$data['L_SHIPPINGOPTIONLABEL' . $index] = $shipping->getLabel();
}
}
}
}
$data['MAXAMT'] = $this->getMaxAmount();
$data['PAYMENTREQUEST_0_TAXAMT'] = $this->getTaxAmount();
$data['PAYMENTREQUEST_0_SHIPPINGAMT'] = $this->getShippingAmount();
$data['PAYMENTREQUEST_0_HANDLINGAMT'] = $this->getHandlingAmount();
$data['PAYMENTREQUEST_0_SHIPDISCAMT'] = $this->getShippingDiscount();
$data['PAYMENTREQUEST_0_INSURANCEAMT'] = $this->getInsuranceAmount();
$data['PAYMENTREQUEST_0_SELLERPAYPALACCOUNTID'] = $this->getSellerPaypalAccountId();
$card = $this->getCard();
if ($card) {
$data['PAYMENTREQUEST_0_SHIPTONAME'] = $card->getName();
$data['PAYMENTREQUEST_0_SHIPTOSTREET'] = $card->getAddress1();
$data['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $card->getAddress2();
$data['PAYMENTREQUEST_0_SHIPTOCITY'] = $card->getCity();
$data['PAYMENTREQUEST_0_SHIPTOSTATE'] = $card->getState();
$data['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $card->getCountry();
$data['PAYMENTREQUEST_0_SHIPTOZIP'] = $card->getPostcode();
$data['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $card->getPhone();
$data['EMAIL'] = $card->getEmail();
}
$billingAgreement = $this->getBillingAgreement();
if ($billingAgreement) {
$data['L_BILLINGTYPE0'] = $billingAgreement->getType();
$data['L_BILLINGAGREEMENTDESCRIPTION0'] = $billingAgreement->getDescription();
if ($billingAgreement->hasPaymentType()) {
$data['L_PAYMENTTYPE0'] = $billingAgreement->getPaymentType();
}
if ($billingAgreement->hasCustomAnnotation()) {
$data['L_BILLINGAGREEMENTCUSTOM0'] = $billingAgreement->getCustomAnnotation();
}
}
$data = array_merge($data, $this->getItemData());
return $data;
}
protected function createResponse($data)
{
return $this->response = new ExpressAuthorizeResponse($this, $data);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Message\RedirectResponseInterface;
/**
* PayPal Express Authorize Response
*/
class ExpressAuthorizeResponse extends Response implements RedirectResponseInterface
{
protected $liveCheckoutEndpoint = 'https://www.paypal.com/cgi-bin/webscr';
protected $testCheckoutEndpoint = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
public function isSuccessful()
{
return false;
}
public function isRedirect()
{
return isset($this->data['ACK']) && in_array($this->data['ACK'], array('Success', 'SuccessWithWarning'));
}
public function getRedirectUrl()
{
return $this->getCheckoutEndpoint().'?'.http_build_query($this->getRedirectQueryParameters(), '', '&');
}
public function getTransactionReference()
{
return isset($this->data['TOKEN']) ? $this->data['TOKEN'] : null;
}
public function getRedirectMethod()
{
return 'GET';
}
public function getRedirectData()
{
return null;
}
protected function getRedirectQueryParameters()
{
return array(
'cmd' => '_express-checkout',
'useraction' => 'commit',
'token' => $this->getTransactionReference(),
);
}
protected function getCheckoutEndpoint()
{
return $this->getRequest()->getTestMode() ? $this->testCheckoutEndpoint : $this->liveCheckoutEndpoint;
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Complete Authorize Request
*/
class ExpressCompleteAuthorizeRequest extends AbstractRequest
{
public function getData()
{
$this->validate('amount');
$data = $this->getBaseData();
$data['METHOD'] = 'DoExpressCheckoutPayment';
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Authorization';
$data['PAYMENTREQUEST_0_AMT'] = $this->getAmount();
$data['PAYMENTREQUEST_0_CURRENCYCODE'] = $this->getCurrency();
$data['PAYMENTREQUEST_0_INVNUM'] = $this->getTransactionId();
$data['PAYMENTREQUEST_0_DESC'] = $this->getDescription();
$data['PAYMENTREQUEST_0_NOTIFYURL'] = $this->getNotifyUrl();
$data['MAXAMT'] = $this->getMaxAmount();
$data['PAYMENTREQUEST_0_TAXAMT'] = $this->getTaxAmount();
$data['PAYMENTREQUEST_0_SHIPPINGAMT'] = $this->getShippingAmount();
$data['PAYMENTREQUEST_0_HANDLINGAMT'] = $this->getHandlingAmount();
$data['PAYMENTREQUEST_0_SHIPDISCAMT'] = $this->getShippingDiscount();
$data['PAYMENTREQUEST_0_INSURANCEAMT'] = $this->getInsuranceAmount();
$data['TOKEN'] = $this->getToken() ? $this->getToken() : $this->httpRequest->query->get('token');
$data['PAYERID'] = $this->getPayerID() ? $this->getPayerID() : $this->httpRequest->query->get('PayerID');
$data = array_merge($data, $this->getItemData());
return $data;
}
public function getPayerID()
{
return $this->getParameter('payerID');
}
public function setPayerID($value)
{
return $this->setParameter('payerID', $value);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Complete Order Request
*/
class ExpressCompleteOrderRequest extends ExpressCompleteAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Order';
return $data;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Complete Purchase Request
*/
class ExpressCompletePurchaseRequest extends ExpressCompleteAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Sale';
return $data;
}
protected function createResponse($data)
{
return $this->response = new ExpressCompletePurchaseResponse($this, $data);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Complete Payment Response
*/
class ExpressCompletePurchaseResponse extends ExpressAuthorizeResponse
{
/*
* Is this complete purchase response successful? Will not be successful if it's a redirect response.
*
* @return bool
*/
public function isSuccessful()
{
$success = isset($this->data['ACK']) && in_array($this->data['ACK'], array('Success', 'SuccessWithWarning'));
return !$this->isRedirect() && $success;
}
/**
* The complete purchase response can be in error where it wants to have your customer return to paypal.
*
* @return bool
*/
public function isRedirect()
{
return isset($this->data['L_ERRORCODE0']) && in_array($this->data['L_ERRORCODE0'], array('10486'));
}
/**
* The transaction reference obtained from the purchase() call can't be used to refund a purchase.
*
* @return string
*/
public function getTransactionReference()
{
if ($this->isSuccessful() && isset($this->data['PAYMENTINFO_0_TRANSACTIONID'])) {
return $this->data['PAYMENTINFO_0_TRANSACTIONID'];
}
return parent::getTransactionReference();
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Fetch Checkout Details Request
*/
class ExpressFetchCheckoutRequest extends AbstractRequest
{
public function getData()
{
$this->validate();
$data = $this->getBaseData();
$data['METHOD'] = 'GetExpressCheckoutDetails';
// token can either be specified directly, or inferred from the GET parameters
if ($this->getToken()) {
$data['TOKEN'] = $this->getToken();
} else {
$data['TOKEN'] = $this->httpRequest->query->get('token');
}
return $data;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express In-Context Authorize Request
*/
class ExpressInContextAuthorizeRequest extends ExpressAuthorizeRequest
{
protected function createResponse($data)
{
return $this->response = new ExpressInContextAuthorizeResponse($this, $data);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express In-Context Authorize Response
*/
class ExpressInContextAuthorizeResponse extends ExpressAuthorizeResponse
{
protected $liveCheckoutEndpoint = 'https://www.paypal.com/checkoutnow';
protected $testCheckoutEndpoint = 'https://www.sandbox.paypal.com/checkoutnow';
protected function getRedirectQueryParameters()
{
return array(
'useraction' => 'commit',
'token' => $this->getTransactionReference(),
);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express In-Context Order Request
*/
class ExpressInContextOrderRequest extends ExpressInContextAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Order';
return $data;
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Order Request
*/
class ExpressOrderRequest extends ExpressAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Order';
return $data;
}
}

View File

@@ -0,0 +1,371 @@
<?php
namespace Omnipay\PayPal\Message;
use DateTime;
/**
* Paypal Express Checkout - Transaction Search
*
* @see https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/
* @see https://developer.paypal.com/docs/classic/express-checkout/ht_searchRetrieveTransactionData-curl-etc/
*
* pt_BR:
* @see https://www.paypal-brasil.com.br/desenvolvedores/tutorial/criando-relatorios-customizados-via-api/
*/
class ExpressTransactionSearchRequest extends AbstractRequest
{
public function getData()
{
$data = $this->getBaseData();
$data['METHOD'] = 'TransactionSearch';
$this->validate('startDate');
$data['STARTDATE'] = $this->getStartDate()->format(DateTime::ISO8601);
if ($this->getEndDate()) {
$data['ENDDATE'] = $this->getEndDate()->format(DateTime::ISO8601);
}
if ($this->getSalutation()) {
$data['SALUTATION'] = $this->getSalutation();
}
if ($this->getFirstName()) {
$data['FIRSTNAME'] = $this->getFirstName();
}
if ($this->getMiddleName()) {
$data['MIDDLENAME'] = $this->getMiddleName();
}
if ($this->getLastName()) {
$data['LASTNAME'] = $this->getLastName();
}
if ($this->getSuffix()) {
$data['SUFFIX'] = $this->getSuffix();
}
if ($this->getEmail()) {
$data['EMAIL'] = $this->getEmail();
}
if ($this->getReceiver()) {
$data['RECEIVER'] = $this->getReceiver();
}
if ($this->getReceiptId()) {
$data['RECEIPTID'] = $this->getReceiptId();
}
if ($this->getTransactionId()) {
$data['TRANSACTIONID'] = $this->getTransactionId();
}
if ($this->getInvoiceNumber()) {
$data['INVNUM'] = $this->getInvoiceNumber();
}
if ($this->getCard()) {
$data['ACCT'] = $this->getCard()->getNumber();
}
if ($this->getAuctionItemNumber()) {
$data['AUCTIONITEMNUMBER'] = $this->getAuctionItemNumber();
}
if ($this->getTransactionClass()) {
$data['TRANSACTIONCLASS'] = $this->getTransactionClass();
}
if ($this->getAmount()) {
$this->validate('currency');
$data['AMT'] = $this->getAmount();
$data['CURRENCYCODE'] = $this->getCurrency();
}
if ($this->getStatus()) {
$data['STATUS'] = $this->getStatus();
}
if ($this->getProfileId()) {
$data['PROFILEID'] = $this->getProfileId();
}
return $data;
}
/**
* @return DateTime|null
*/
public function getStartDate()
{
return $this->getParameter('startDate');
}
/**
* @param DateTime|string $date
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setStartDate($date)
{
if (! $date instanceof DateTime) {
$date = new DateTime($date);
}
return $this->setParameter('startDate', $date);
}
/**
* @return DateTime|null
*/
public function getEndDate()
{
return $this->getParameter('endDate');
}
/**
* @param DateTime|string $date
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setEndDate($date)
{
if (! $date instanceof DateTime) {
$date = new DateTime($date);
}
return $this->setParameter('endDate', $date);
}
/**
* @return string
*/
public function getSalutation()
{
return $this->getParameter('salutation');
}
/**
* @param string $salutation
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setSalutation($salutation)
{
return $this->setParameter('salutation', $salutation);
}
/**
* @return string
*/
public function getFirstName()
{
return $this->getParameter('firstName');
}
/**
* @param string $firstName
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setFirstName($firstName)
{
return $this->setParameter('firstName', $firstName);
}
/**
* @return string
*/
public function getMiddleName()
{
return $this->getParameter('middleName');
}
/**
* @param string $middleName
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setMiddleName($middleName)
{
return $this->setParameter('middleName', $middleName);
}
/**
* @return string
*/
public function getLastName()
{
return $this->getParameter('lastName');
}
/**
* @param string $lastName
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setLastName($lastName)
{
return $this->setParameter('lastName', $lastName);
}
/**
* @return string
*/
public function getSuffix()
{
return $this->getParameter('suffix');
}
/**
* @param string $suffix
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setSuffix($suffix)
{
return $this->setParameter('suffix', $suffix);
}
/**
* @return string
*/
public function getEmail()
{
return $this->getParameter('email');
}
/**
* @param string $email
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setEmail($email)
{
return $this->setParameter('email', $email);
}
/**
* @return string
*/
public function getReceiver()
{
return $this->getParameter('receiver');
}
/**
* @param string $receiver
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setReceiver($receiver)
{
return $this->setParameter('receiver', $receiver);
}
/**
* @return string
*/
public function getReceiptId()
{
return $this->getParameter('receiptId');
}
/**
* @param string $receiptId
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setReceiptId($receiptId)
{
return $this->setParameter('receiptId', $receiptId);
}
/**
* @return string
*/
public function getInvoiceNumber()
{
return $this->getParameter('invoiceNumber');
}
/**
* @param string $invoiceNumber
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setInvoiceNumber($invoiceNumber)
{
return $this->setParameter('invoiceNumber', $invoiceNumber);
}
/**
* @return string
*/
public function getAuctionItemNumber()
{
return $this->getParameter('auctionItemNumber');
}
/**
* @param string $auctionItemNumber
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setAuctionItemNumber($auctionItemNumber)
{
return $this->setParameter('auctionItemNumber', $auctionItemNumber);
}
/**
* @return string
*/
public function getTransactionClass()
{
return $this->getParameter('transactionClass');
}
/**
* @param string $transactionClass
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setTransactionClass($transactionClass)
{
return $this->setParameter('transactionClass', $transactionClass);
}
/**
* @return string
*/
public function getStatus()
{
return $this->getParameter('status');
}
/**
* @param string $status
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setStatus($status)
{
return $this->setParameter('status', $status);
}
/**
* @return string
*/
public function getProfileId()
{
return $this->getParameter('profileId');
}
/**
* @param string $profileId
* @return \Omnipay\Common\Message\AbstractRequest
*/
public function setProfileId($profileId)
{
return $this->setParameter('profileId', $profileId);
}
/**
* @return ExpressTransactionSearchResponse
*/
public function createResponse($data)
{
return $this->response = new ExpressTransactionSearchResponse($this, $data);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Message\RequestInterface;
/**
* Response for Transaction Search request
*/
class ExpressTransactionSearchResponse extends Response
{
public function __construct(RequestInterface $request, $data)
{
parent::__construct($request, $data);
$payments = array();
foreach ($this->data as $key => $value) {
if ($this->isSuccessful()
&& preg_match('/(L_)?(?<key>[A-Za-z]+)(?<n>[0-9]+)/', $key, $matches)
) {
$payments[$matches['n']][$matches['key']] = $value;
unset($this->data[$key]);
}
}
$this->data['payments'] = $payments;
}
public function getPayments()
{
return $this->data['payments'];
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Express Void Request
*/
class ExpressVoidRequest extends AbstractRequest
{
public function getData()
{
$this->validate('transactionReference');
$data = $this->getBaseData();
$data['METHOD'] = 'DoVoid';
$data['AUTHORIZATIONID'] = $this->getTransactionReference();
return $data;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Fetch Transaction Request
*/
class FetchTransactionRequest extends AbstractRequest
{
public function getData()
{
$this->validate('transactionReference');
$data = $this->getBaseData();
$data['METHOD'] = 'GetTransactionDetails';
$data['TRANSACTIONID'] = $this->getTransactionReference();
return $data;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Pro Authorize Request
*/
class ProAuthorizeRequest extends AbstractRequest
{
public function getData()
{
$this->validate('amount', 'card');
$this->getCard()->validate();
$data = $this->getBaseData();
$data['METHOD'] = 'DoDirectPayment';
$data['PAYMENTACTION'] = 'Authorization';
$data['AMT'] = $this->getAmount();
$data['CURRENCYCODE'] = $this->getCurrency();
$data['INVNUM'] = $this->getTransactionId();
$data['DESC'] = $this->getDescription();
// add credit card details
$data['ACCT'] = $this->getCard()->getNumber();
$data['CREDITCARDTYPE'] = $this->getCard()->getBrand();
$data['EXPDATE'] = $this->getCard()->getExpiryDate('mY');
$data['STARTDATE'] = $this->getCard()->getStartDate('mY');
$data['CVV2'] = $this->getCard()->getCvv();
$data['ISSUENUMBER'] = $this->getCard()->getIssueNumber();
$data['IPADDRESS'] = $this->getClientIp();
$data['FIRSTNAME'] = $this->getCard()->getFirstName();
$data['LASTNAME'] = $this->getCard()->getLastName();
$data['EMAIL'] = $this->getCard()->getEmail();
$data['STREET'] = $this->getCard()->getAddress1();
$data['STREET2'] = $this->getCard()->getAddress2();
$data['CITY'] = $this->getCard()->getCity();
$data['STATE'] = $this->getCard()->getState();
$data['ZIP'] = $this->getCard()->getPostcode();
$data['COUNTRYCODE'] = strtoupper($this->getCard()->getCountry());
return $data;
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Pro Purchase Request
*/
class ProPurchaseRequest extends ProAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['PAYMENTACTION'] = 'Sale';
return $data;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Omnipay\PayPal\Message;
/**
* PayPal Refund Request
*/
class RefundRequest extends AbstractRequest
{
public function getData()
{
$this->validate('transactionReference');
$data = $this->getBaseData();
$data['METHOD'] = 'RefundTransaction';
$data['TRANSACTIONID'] = $this->getTransactionReference();
$data['REFUNDTYPE'] = 'Full';
if ($this->getAmount() > 0) {
$data['REFUNDTYPE'] = 'Partial';
$data['AMT'] = $this->getAmount();
$data['CURRENCYCODE'] = $this->getCurrency();
}
return $data;
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Message\AbstractResponse;
use Omnipay\Common\Message\RequestInterface;
/**
* PayPal Response
*/
class Response extends AbstractResponse
{
public function __construct(RequestInterface $request, $data)
{
$this->request = $request;
parse_str($data, $this->data);
}
public function isPending()
{
return isset($this->data['PAYMENTINFO_0_PAYMENTSTATUS'])
&& $this->data['PAYMENTINFO_0_PAYMENTSTATUS'] == 'Pending';
}
public function isSuccessful()
{
return isset($this->data['ACK']) && in_array($this->data['ACK'], array('Success', 'SuccessWithWarning'));
}
public function getTransactionReference()
{
foreach (array('REFUNDTRANSACTIONID',
'TRANSACTIONID',
'PAYMENTINFO_0_TRANSACTIONID',
'AUTHORIZATIONID') as $key) {
if (isset($this->data[$key])) {
return $this->data[$key];
}
}
}
public function getMessage()
{
return isset($this->data['L_LONGMESSAGE0']) ? $this->data['L_LONGMESSAGE0'] : null;
}
}

View File

@@ -0,0 +1,366 @@
<?php
/**
* PayPal REST Authorize Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Authorize Request
*
* To collect payment at a later time, first authorize a payment using the /payment resource.
* You can then capture the payment to complete the sale and collect payment.
*
* This looks exactly like a RestPurchaseRequest object except that the intent is
* set to "authorize" (to authorize a payment to be captured later) rather than
* "sale" (which is used to capture a payment immediately).
*
* ### Example
*
* #### Initialize Gateway
*
* <code>
* // Create a gateway for the PayPal RestGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
* </code>
*
* #### 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.
*
* </code>
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
* $card = new CreditCard(array(
* 'firstName' => 'Example',
* 'lastName' => 'User',
* 'number' => '4111111111111111',
* 'expiryMonth' => '01',
* 'expiryYear' => '2020',
* 'cvv' => '123',
* 'billingAddress1' => '1 Scrubby Creek Road',
* 'billingCountry' => 'AU',
* 'billingCity' => 'Scrubby Creek',
* 'billingPostcode' => '4999',
* 'billingState' => 'QLD',
* ));
*
* // Do an authorisation transaction on the gateway
* $transaction = $gateway->authorize(array(
* 'amount' => '10.00',
* 'currency' => 'AUD',
* 'description' => 'This is a test authorize transaction.',
* 'card' => $card,
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Authorize transaction was successful!\n";
* // Find the authorization ID
* $auth_id = $response->getTransactionReference();
* }
* </code>
*
* Direct credit card payment and related features are restricted in
* some countries.
* 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.
*
* <code>
* $transaction = MyClass::saveTransaction($some_data);
* $txn_id = $transaction->getId();
* </code>
*
* Step 2 is to send the purchase request.
*
* </code>
* // 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";
* }
* </code>
*
* 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.
*
* </code>
* 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());
* }
* </code>
*
* 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.
*
* <code>
* $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.
* }
* </code>
*
* #### 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
* @see RestCaptureRequest
* @see RestPurchaseRequest
*/
class RestAuthorizeRequest extends AbstractRestRequest
{
public function getData()
{
$data = array(
'intent' => 'authorize',
'payer' => array(
'payment_method' => 'credit_card',
'funding_instruments' => array()
),
'transactions' => array(
array(
'description' => $this->getDescription(),
'amount' => array(
'total' => $this->getAmount(),
'currency' => $this->getCurrency(),
),
'invoice_number' => $this->getTransactionId()
)
),
'experience_profile_id' => $this->getExperienceProfileId()
);
$items = $this->getItems();
if ($items) {
$itemList = array();
foreach ($items as $n => $item) {
$itemList[] = array(
'name' => $item->getName(),
'description' => $item->getDescription(),
'quantity' => $item->getQuantity(),
'price' => $this->formatCurrency($item->getPrice()),
'currency' => $this->getCurrency()
);
}
$data['transactions'][0]['item_list']["items"] = $itemList;
}
if ($this->getCardReference()) {
$this->validate('amount');
$data['payer']['funding_instruments'][] = array(
'credit_card_token' => array(
'credit_card_id' => $this->getCardReference(),
),
);
} elseif ($this->getCard()) {
$this->validate('amount', 'card');
$this->getCard()->validate();
$data['payer']['funding_instruments'][] = array(
'credit_card' => array(
'number' => $this->getCard()->getNumber(),
'type' => $this->getCard()->getBrand(),
'expire_month' => $this->getCard()->getExpiryMonth(),
'expire_year' => $this->getCard()->getExpiryYear(),
'cvv2' => $this->getCard()->getCvv(),
'first_name' => $this->getCard()->getFirstName(),
'last_name' => $this->getCard()->getLastName(),
'billing_address' => array(
'line1' => $this->getCard()->getAddress1(),
//'line2' => $this->getCard()->getAddress2(),
'city' => $this->getCard()->getCity(),
'state' => $this->getCard()->getState(),
'postal_code' => $this->getCard()->getPostcode(),
'country_code' => strtoupper($this->getCard()->getCountry()),
)
)
);
// There's currently a quirk with the REST API that requires line2 to be
// non-empty if it's present. Jul 14, 2014
$line2 = $this->getCard()->getAddress2();
if (!empty($line2)) {
$data['payer']['funding_instruments'][0]['credit_card']['billing_address']['line2'] = $line2;
}
} else {
$this->validate('amount', 'returnUrl', 'cancelUrl');
unset($data['payer']['funding_instruments']);
$data['payer']['payment_method'] = 'paypal';
$data['redirect_urls'] = array(
'return_url' => $this->getReturnUrl(),
'cancel_url' => $this->getCancelUrl(),
);
}
return $data;
}
/**
* Get the experience profile id
*
* @return string
*/
public function getExperienceProfileId()
{
return $this->getParameter('experienceProfileId');
}
/**
* Set the experience profile id
*
* @param string $value
* @return RestAuthorizeRequest provides a fluent interface.
*/
public function setExperienceProfileId($value)
{
return $this->setParameter('experienceProfileId', $value);
}
/**
* Get transaction description.
*
* The REST API does not currently have support for passing an invoice number
* or transaction ID.
*
* @return string
*/
public function getDescription()
{
$id = $this->getTransactionId();
$desc = parent::getDescription();
if (empty($id)) {
return $desc;
} elseif (empty($desc)) {
return $id;
} else {
return "$id : $desc";
}
}
/**
* Get transaction endpoint.
*
* Authorization of payments is done using the /payment resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/payment';
}
protected function createResponse($data, $statusCode)
{
return $this->response = new RestAuthorizeResponse($this, $data, $statusCode);
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* PayPal REST Authorize Response
*/
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Message\RedirectResponseInterface;
/**
* PayPal REST Authorize Response
*/
class RestAuthorizeResponse extends RestResponse implements RedirectResponseInterface
{
public function isSuccessful()
{
return empty($this->data['error']) && $this->getCode() == 201;
}
public function isRedirect()
{
return $this->getRedirectUrl() !== null;
}
public function getRedirectUrl()
{
if (isset($this->data['links']) && is_array($this->data['links'])) {
foreach ($this->data['links'] as $key => $value) {
if ($value['rel'] == 'approval_url') {
return $value['href'];
}
}
}
return null;
}
/**
* Get the URL to complete (execute) the purchase or agreement.
*
* The URL is embedded in the links section of the purchase or create
* subscription request response.
*
* @return string
*/
public function getCompleteUrl()
{
if (isset($this->data['links']) && is_array($this->data['links'])) {
foreach ($this->data['links'] as $key => $value) {
if ($value['rel'] == 'execute') {
return $value['href'];
}
}
}
return null;
}
public function getTransactionReference()
{
// The transaction reference for a paypal purchase request or for a
// paypal create subscription request ends up in the execute URL
// in the links section of the response.
$completeUrl = $this->getCompleteUrl();
if (empty($completeUrl)) {
return parent::getTransactionReference();
}
$urlParts = explode('/', $completeUrl);
// The last element of the URL should be "execute"
$execute = end($urlParts);
if (!in_array($execute, array('execute', 'agreement-execute'))) {
return parent::getTransactionReference();
}
// The penultimate element should be the transaction reference
return prev($urlParts);
}
/**
* Get the required redirect method (either GET or POST).
*
* @return string
*/
public function getRedirectMethod()
{
return 'GET';
}
/**
* Gets the redirect form data array, if the redirect method is POST.
*
* @return null
*/
public function getRedirectData()
{
return null;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* PayPal REST Cancel Subscription Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Cancel Subscription Request
*
* Use this call to cancel an agreement after the buyer approves it.
*
* ### Request Data
*
* Pass the agreement id in the URI of a POST call. Also include a description,
* which is the reason for cancelling the subscription.
*
* ### Example
*
* To create the agreement, see the code example in RestCreateSubscriptionRequest.
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a cancel subscription transaction on the gateway
* $transaction = $gateway->cancelSubscription(array(
* 'transactionReference' => $subscription_id,
* 'description' => "Cancelling the agreement.",
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Cancel Subscription transaction was successful!\n";
* }
* </code>
*
* Note that the subscription_id that you get from calling the response's
* getTransactionReference() method at the end of the completeSubscription
* call will be different to the one that you got after calling the response's
* getTransactionReference() method at the end of the createSubscription
* call. The one that you get from completeSubscription is the correct
* one to use going forwards (e.g. for cancelling or updating the subscription).
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/cancel \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{
* "note": "Canceling the agreement."
* }'
* </code>
*
* @link https://developer.paypal.com/docs/api/#cancel-an-agreement
* @see RestCreateSubscriptionRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestCancelSubscriptionRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference', 'description');
$data = array(
'note' => $this->getDescription(),
);
return $data;
}
/**
* Get transaction endpoint.
*
* Subscriptions are executed using the /billing-agreements resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements/' .
$this->getTransactionReference() . '/cancel';
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* PayPal REST Capture Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Capture Request
*
* Use this resource to capture and process a previously created authorization.
* To use this resource, the original payment call must have the intent set to
* authorize.
*
* To capture payment, make a call to /v1/payments/authorization/{authorization_id}/capture
* with the authorization ID in the URI along with an amount object. For a
* partial capture, you can provide a lower amount. Additionally, you can explicitly
* 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
* and that the authorization ID returned from the authorization is held in $auth_id.
* See RestAuthorizeRequest for the first part of this example transaction:
*
* <code>
* // Once the transaction has been authorized, we can capture it for final payment.
* $transaction = $gateway->capture(array(
* 'amount' => '10.00',
* 'currency' => 'AUD',
* ));
* $transaction->setTransactionReference($auth_id);
* $response = $transaction->send();
* </code>
*
* @see RestAuthorizeRequest
* @link https://developer.paypal.com/docs/api/#capture-an-authorization
*/
class RestCaptureRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference', 'amount');
return array(
'amount' => array(
'currency' => $this->getCurrency(),
'total' => $this->getAmount(),
),
'is_final_capture' => true,
);
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/authorization/' . $this->getTransactionReference() . '/capture';
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* PayPal REST Complete Purchase Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Complete Purchase Request
*
* Use this message to execute (complete) a PayPal payment that has been
* approved by the payer. You can optionally update transaction information
* when executing the payment by passing in one or more transactions.
*
* This call only works after a buyer has approved the payment using the
* provided PayPal approval URL.
*
* ### 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:
*
* <code>
* $paymentId = $_GET['paymentId'];
* $payerId = $_GET['payerId'];
*
* // Once the transaction has been approved, we need to complete it.
* $transaction = $gateway->completePurchase(array(
* 'payer_id' => $payerId,
* 'transactionReference' => $paymentId,
* ));
* $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.
* }
* </code>
*
* @see RestPurchaseRequest
* @link https://developer.paypal.com/docs/api/#execute-an-approved-paypal-payment
*/
class RestCompletePurchaseRequest extends AbstractRestRequest
{
/**
* Get the raw data array for this message. The format of this varies from gateway to
* gateway, but will usually be either an associative array, or a SimpleXMLElement.
*
* @return mixed
*/
public function getData()
{
$this->validate('transactionReference', 'payerId');
$data = array(
'payer_id' => $this->getPayerId()
);
return $data;
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/payment/' . $this->getTransactionReference() . '/execute';
}
}

View File

@@ -0,0 +1,120 @@
<?php
/**
* PayPal REST Complete Subscription Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Complete Subscription Request
*
* Use this call to execute an agreement after the buyer approves it.
*
* Note: This request is only necessary for PayPal payments. Billing
* agreements for credit card payments execute automatically at the time
* of creation and so this request is not necessary for credit card payments.
*
* ### Request Data
*
* Pass the token in the URI of a POST call to execute the subscription
* agreement after buyer approval. You can find the token in the execute
* link returned by the request to create a billing agreement.
*
* No other data is required.
*
* ### Example
*
* To create the agreement, see the code example in RestCreateSubscriptionRequest.
*
* At the completion of a createSubscription call, the customer should be
* redirected to the redirect URL contained in $response->getRedirectUrl(). Once
* the customer has approved the agreement and be returned to the returnUrl
* in the call. The returnUrl can contain the following code to complete
* the agreement:
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a complete subscription transaction on the gateway
* $transaction = $gateway->completeSubscription(array(
* 'transactionReference' => $subscription_id,
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Complete Subscription transaction was successful!\n";
* $subscription_id = $response->getTransactionReference();
* echo "Subscription reference = " . $subscription_id;
* }
* </code>
*
* Note that the subscription_id that you get from calling the response's
* getTransactionReference() method at the end of the completeSubscription
* call will be different to the one that you got after calling the response's
* getTransactionReference() method at the end of the createSubscription
* call. The one that you get from completeSubscription is the correct
* one to use going forwards (e.g. for cancelling or updating the subscription).
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-agreements/EC-0JP008296V451950C/agreement-execute \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{}'
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "id": "I-0LN988D3JACS",
* "links": [
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS",
* "rel": "self",
* "method": "GET"
* }
* ]
* }
* </code>
*
* @link https://developer.paypal.com/docs/api/#execute-an-agreement
* @see RestCreateSubscriptionRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestCompleteSubscriptionRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
$data = array();
return $data;
}
/**
* Get transaction endpoint.
*
* Subscriptions are executed using the /billing-agreements resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements/' .
$this->getTransactionReference() . '/agreement-execute';
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* PayPal REST Create Card Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Create Card Request
*
* PayPal offers merchants a /vault API to store sensitive details
* like credit card related details.
*
* You can currently use the /vault API to store credit card details
* 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.
*
* Direct credit card payment and related features are restricted in
* some countries.
* As of January 2015 these transactions are only supported in the UK
* and in the USA.
*
* Example:
*
* <code>
* // Create a gateway for the PayPal RestGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
* $card = new CreditCard(array(
* 'firstName' => 'Example',
* 'lastName' => 'User',
* 'number' => '4111111111111111',
* 'expiryMonth' => '01',
* 'expiryYear' => '2020',
* 'cvv' => '123',
* 'billingAddress1' => '1 Scrubby Creek Road',
* 'billingCountry' => 'AU',
* 'billingCity' => 'Scrubby Creek',
* 'billingPostcode' => '4999',
* 'billingState' => 'QLD',
* ));
*
* // Do a create card transaction on the gateway
* $transaction = $gateway->createCard(array(
* 'card' => $card,
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Create card transaction was successful!\n";
* // Find the card ID
* $card_id = $response->getTransactionReference();
* }
* </code>
*
* @link https://developer.paypal.com/docs/api/#vault
* @link https://developer.paypal.com/docs/api/#store-a-credit-card
* @link http://bit.ly/1wUQ33R
*/
class RestCreateCardRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('card');
$this->getCard()->validate();
$data = array(
'number' => $this->getCard()->getNumber(),
'type' => $this->getCard()->getBrand(),
'expire_month' => $this->getCard()->getExpiryMonth(),
'expire_year' => $this->getCard()->getExpiryYear(),
'cvv2' => $this->getCard()->getCvv(),
'first_name' => $this->getCard()->getFirstName(),
'last_name' => $this->getCard()->getLastName(),
'billing_address' => array(
'line1' => $this->getCard()->getAddress1(),
//'line2' => $this->getCard()->getAddress2(),
'city' => $this->getCard()->getCity(),
'state' => $this->getCard()->getState(),
'postal_code' => $this->getCard()->getPostcode(),
'country_code' => strtoupper($this->getCard()->getCountry()),
)
);
// There's currently a quirk with the REST API that requires line2 to be
// non-empty if it's present. Jul 14, 2014
$line2 = $this->getCard()->getAddress2();
if (!empty($line2)) {
$data['billing_address']['line2'] = $line2;
}
return $data;
}
protected function getEndpoint()
{
return parent::getEndpoint() . '/vault/credit-cards';
}
}

View File

@@ -0,0 +1,323 @@
<?php
/**
* PayPal REST Create Plan Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Create Plan Request
*
* PayPal offers merchants a /billing-plans resource for providing billing plans
* to users for recurring payments.
*
* After the billing plan is created, the /billing-agreements resource provides
* billing agreements so that users can agree to be billed for the plans.
*
* You can create an empty billing plan and add a trial period and/or regular
* billing. Alternatively, you can create a fully loaded plan that includes both
* a trial period and regular billing. Note: By default, a created billing plan
* is in a CREATED state. A user cannot subscribe to the billing plan unless it
* has been set to the ACTIVE state.
*
* ### Request Data
*
* In order to create a new billing plan you must submit the following details:
*
* * name (string). Required.
* * description (string). Required.
* * type (string). Allowed values: FIXED, INFINITE. Required.
* * payment_definitions (array)
* * merchant_preferences (object)
*
* ### Example
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a create plan transaction on the gateway
* $transaction = $gateway->createPlan(array(
* 'name' => 'Test Plan',
* 'description' => 'A plan created for testing',
* 'type' => $gateway::BILLING_PLAN_TYPE_FIXED,
* 'paymentDefinitions' => [
* [
* 'name' => 'Monthly Payments for 12 months',
* 'type' => $gateway::PAYMENT_TRIAL,
* 'frequency' => $gateway::BILLING_PLAN_FREQUENCY_MONTH,
* 'frequency_interval' => 1,
* 'cycles' => 12,
* 'amount' => ['value' => 10.00, 'currency' => 'USD'],
* ],
* ],
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Create Plan transaction was successful!\n";
* $plan_id = $response->getTransactionReference();
* echo "Plan reference = " . $plan_id . "\n";
* }
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-plans \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{
* "name": "T-Shirt of the Month Club Plan",
* "description": "Template creation.",
* "type": "fixed",
* "payment_definitions": [
* {
* "name": "Regular Payments",
* "type": "REGULAR",
* "frequency": "MONTH",
* "frequency_interval": "2",
* "amount": {
* "value": "100",
* "currency": "USD"
* },
* "cycles": "12",
* "charge_models": [
* {
* "type": "SHIPPING",
* "amount": {
* "value": "10",
* "currency": "USD"
* }
* },
* {
* "type": "TAX",
* "amount": {
* "value": "12",
* "currency": "USD"
* }
* }
* ]
* }
* ],
* "merchant_preferences": {
* "setup_fee": {
* "value": "1",
* "currency": "USD"
* },
* "return_url": "http://www.return.com",
* "cancel_url": "http://www.cancel.com",
* "auto_bill_amount": "YES",
* "initial_fail_amount_action": "CONTINUE",
* "max_fail_attempts": "0"
* }
* }'
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "id": "P-94458432VR012762KRWBZEUA",
* "state": "CREATED",
* "name": "T-Shirt of the Month Club Plan",
* "description": "Template creation.",
* "type": "FIXED",
* "payment_definitions": [
* {
* "id": "PD-50606817NF8063316RWBZEUA",
* "name": "Regular Payments",
* "type": "REGULAR",
* "frequency": "Month",
* "amount": {
* "currency": "USD",
* "value": "100"
* },
* "charge_models": [
* {
* "id": "CHM-55M5618301871492MRWBZEUA",
* "type": "SHIPPING",
* "amount": {
* "currency": "USD",
* "value": "10"
* }
* },
* {
* "id": "CHM-92S85978TN737850VRWBZEUA",
* "type": "TAX",
* "amount": {
* "currency": "USD",
* "value": "12"
* }
* }
* ],
* "cycles": "12",
* "frequency_interval": "2"
* }
* ],
* "merchant_preferences": {
* "setup_fee": {
* "currency": "USD",
* "value": "1"
* },
* "max_fail_attempts": "0",
* "return_url": "http://www.return.com",
* "cancel_url": "http://www.cancel.com",
* "auto_bill_amount": "YES",
* "initial_fail_amount_action": "CONTINUE"
* },
* "create_time": "2014-07-31T17:41:55.920Z",
* "update_time": "2014-07-31T17:41:55.920Z",
* "links": [
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-plans/P-94458432VR012762KRWBZEUA",
* "rel": "self",
* "method": "GET"
* }
* ]
* }
* </code>
*
* @link https://developer.paypal.com/docs/api/#create-a-plan
* @see Omnipay\PayPal\RestGateway
*/
class RestCreatePlanRequest extends AbstractRestRequest
{
/**
* Get the plan name
*
* @return string
*/
public function getName()
{
return $this->getParameter('name');
}
/**
* Set the plan name
*
* @param string $value
* @return RestCreatePlanRequest provides a fluent interface.
*/
public function setName($value)
{
return $this->setParameter('name', $value);
}
/**
* Get the plan type
*
* @return string
*/
public function getType()
{
return $this->getParameter('type');
}
/**
* Set the plan type
*
* @param string $value either RestGateway::BILLING_PLAN_TYPE_FIXED
* or RestGateway::BILLING_PLAN_TYPE_INFINITE
* @return RestCreatePlanRequest provides a fluent interface.
*/
public function setType($value)
{
return $this->setParameter('type', $value);
}
/**
* Get the plan payment definitions
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#paymentdefinition-object
*/
public function getPaymentDefinitions()
{
return $this->getParameter('paymentDefinitions');
}
/**
* Set the plan payment definitions
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreatePlanRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#paymentdefinition-object
*/
public function setPaymentDefinitions(array $value)
{
return $this->setParameter('paymentDefinitions', $value);
}
/**
* Get the plan merchant preferences
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#merchantpreferences-object
*/
public function getMerchantPreferences()
{
return $this->getParameter('merchantPreferences');
}
/**
* Set the plan merchant preferences
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreatePlanRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#merchantpreferences-object
*/
public function setMerchantPreferences(array $value)
{
return $this->setParameter('merchantPreferences', $value);
}
public function getData()
{
$this->validate('name', 'description', 'type');
$data = array(
'name' => $this->getName(),
'description' => $this->getDescription(),
'type' => $this->getType(),
'payment_definitions' => $this->getPaymentDefinitions(),
'merchant_preferences' => $this->getMerchantPreferences(),
);
return $data;
}
/**
* Get transaction endpoint.
*
* Billing plans are created using the /billing-plans resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-plans';
}
}

View File

@@ -0,0 +1,457 @@
<?php
/**
* PayPal REST Create Subscription Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Create Subscription Request
*
* Use this call to create a billing agreement for the buyer. The response
* for this call includes these HATEOAS links: an approval_url link and an
* execute link. Each returned link includes the token for the agreement.
*
* For PayPal payments:
*
* * After successfully creating the agreement, direct the user to the
* approval_url on the PayPal site so that the user can approve the agreement.
* * Call the execute link to execute the billing agreement.
*
* Note: Billing agreements for credit card payments execute automatically
* when created. There is no need for the user to approve the agreement or
* to execute the agreement.
*
* ### Request Data
*
* Pass the agreement details in the body of a POST call, including the
* following agreement object properties:
*
* * name (string). Required.
* * description (string). Required.
* * start_date (string). Format yyyy-MM-dd z, as defined in ISO8601. Required.
* * agreement_details (array)
* * payer (array). Required
* * shipping_address (array). Should be provided if it is different to the
* default address.
* * override_merchant_preferences (array).
* * override_charge_models (array).
* * plan (array). Required.
*
* ### Example
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a create plan transaction on the gateway
* $transaction = $gateway->createPlan(array(
* 'name' => 'Test Plan',
* 'description' => 'A plan created for testing',
* 'type' => $gateway::BILLING_PLAN_TYPE_FIXED,
* 'paymentDefinitions' => [
* [
* 'name' => 'Monthly Payments for 12 months',
* 'type' => $gateway::PAYMENT_TRIAL,
* 'frequency' => $gateway::BILLING_PLAN_FREQUENCY_MONTH,
* 'frequency_interval' => 1,
* 'cycles' => 12,
* 'amount' => ['value' => 10.00, 'currency' => 'USD'],
* ],
* ],
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Create Plan transaction was successful!\n";
* $plan_id = $response->getTransactionReference();
* echo "Plan reference = " . $plan_id . "\n";
* }
*
* // Do a create subscription transaction on the gateway
* $transaction = $gateway->createSubscription(array(
* 'name' => 'Test Subscription',
* 'description' => 'A subscription created for testing',
* 'startDate' => new \DateTime(), // now
* 'planId' => $plan_id,
* 'payerDetails => ['payment_method' => 'paypal'],
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Create Subscription transaction was successful!\n";
* if ($response->isRedirect()) {
* echo "Response is a redirect\n";
* echo "Redirect URL = " . $response->getRedirectUrl();
* $subscription_id = $response->getTransactionReference();
* echo "Subscription reference = " . $subscription_id;
* }
* }
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-agreements \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{
* "name": "T-Shirt of the Month Club Agreement",
* "description": "Agreement for T-Shirt of the Month Club Plan",
* "start_date": "2015-02-19T00:37:04Z",
* "plan": {
* "id": "P-94458432VR012762KRWBZEUA"
* },
* "payer": {
* "payment_method": "paypal"
* },
* "shipping_address": {
* "line1": "111 First Street",
* "city": "Saratoga",
* "state": "CA",
* "postal_code": "95070",
* "country_code": "US"
* }
* }'
* }'
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "name": "T-Shirt of the Month Club Agreement",
* "description": "Agreement for T-Shirt of the Month Club Plan",
* "plan": {
* "id": "P-94458432VR012762KRWBZEUA",
* "state": "ACTIVE",
* "name": "T-Shirt of the Month Club Plan",
* "description": "Template creation.",
* "type": "FIXED",
* "payment_definitions": [
* {
* "id": "PD-50606817NF8063316RWBZEUA",
* "name": "Regular Payments",
* "type": "REGULAR",
* "frequency": "Month",
* "amount": {
* "currency": "USD",
* "value": "100"
* },
* "charge_models": [
* {
* "id": "CHM-92S85978TN737850VRWBZEUA",
* "type": "TAX",
* "amount": {
* "currency": "USD",
* "value": "12"
* }
* },
* {
* "id": "CHM-55M5618301871492MRWBZEUA",
* "type": "SHIPPING",
* "amount": {
* "currency": "USD",
* "value": "10"
* }
* }
* ],
* "cycles": "12",
* "frequency_interval": "2"
* }
* ],
* "merchant_preferences": {
* "setup_fee": {
* "currency": "USD",
* "value": "1"
* },
* "max_fail_attempts": "0",
* "return_url": "http://www.return.com",
* "cancel_url": "http://www.cancel.com",
* "auto_bill_amount": "YES",
* "initial_fail_amount_action": "CONTINUE"
* }
* },
* "links": [
* {
* "href": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-0JP008296V451950C",
* "rel": "approval_url",
* "method": "REDIRECT"
* },
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-agreements/EC-0JP008296V451950C/agreement-execute",
* "rel": "execute",
* "method": "POST"
* }
* ],
* "start_date": "2015-02-19T00:37:04Z"
* }
* </code>
*
* ### Known Issues
*
* PayPal subscription payments cannot be refunded. PayPal is working on this functionality
* for their future API release. In order to refund a PayPal subscription payment, you will
* need to use the PayPal web interface to refund it manually.
*
* @link https://developer.paypal.com/docs/api/#create-an-agreement
* @see RestCreatePlanRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestCreateSubscriptionRequest extends AbstractRestRequest
{
/**
* Get the agreement name
*
* @return string
*/
public function getName()
{
return $this->getParameter('name');
}
/**
* Set the agreement name
*
* @param string $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
*/
public function setName($value)
{
return $this->setParameter('name', $value);
}
/**
* Get the plan ID
*
* @return string
*/
public function getPlanId()
{
return $this->getParameter('planId');
}
/**
* Set the plan ID
*
* @param string $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
*/
public function setPlanId($value)
{
return $this->setParameter('planId', $value);
}
/**
* Get the agreement start date
*
* @return \DateTime
*/
public function getStartDate()
{
return $this->getParameter('startDate');
}
/**
* Set the agreement start date
*
* @param \DateTime $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
*/
public function setStartDate(\DateTime $value)
{
return $this->setParameter('startDate', $value);
}
/**
* Get the agreement details
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#agreementdetails-object
*/
public function getAgreementDetails()
{
return $this->getParameter('agreementDetails');
}
/**
* Set the agreement details
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#agreementdetails-object
*/
public function setAgreementDetails(array $value)
{
return $this->setParameter('agreementDetails', $value);
}
/**
* Get the payer details
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#payer-object
*/
public function getPayerDetails()
{
return $this->getParameter('payerDetails');
}
/**
* Set the payer details
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#payer-object
*/
public function setPayerDetails(array $value)
{
return $this->setParameter('payerDetails', $value);
}
/**
* Get the shipping address
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#address-object
*/
public function getShippingAddress()
{
return $this->getParameter('shippingAddress');
}
/**
* Set the shipping address
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#address-object
*/
public function setShippingAddress(array $value)
{
return $this->setParameter('shippingAddress', $value);
}
/**
* Get preferences to override the plan merchant preferences
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#merchantpreferences-object
*/
public function getMerchantPreferences()
{
return $this->getParameter('merchantPreferences');
}
/**
* Set preferences to override the plan merchant preferences
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#merchantpreferences-object
*/
public function setMerchantPreferences(array $value)
{
return $this->setParameter('merchantPreferences', $value);
}
/**
* Get charge model to override the plan charge model
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @return array
* @link https://developer.paypal.com/docs/api/#overridechargemodel-object
*/
public function getChargeModel()
{
return $this->getParameter('chargeModel');
}
/**
* Set preferences to override the plan merchant preferences
*
* See the class documentation and the PayPal REST API documentation for
* a description of the array elements.
*
* @param array $value
* @return RestCreateSubscriptionRequest provides a fluent interface.
* @link https://developer.paypal.com/docs/api/#merchantpreferences-object
*/
public function setChargeModel(array $value)
{
return $this->setParameter('chargeModel', $value);
}
public function getData()
{
$this->validate('name', 'description', 'startDate', 'payerDetails', 'planId');
$data = array(
'name' => $this->getName(),
'description' => $this->getDescription(),
'start_date' => $this->getStartDate()->format('c'),
'agreement_details' => $this->getAgreementDetails(),
'payer' => $this->getPayerDetails(),
'plan' => array(
'id' => $this->getPlanId(),
),
'shipping_address' => $this->getShippingAddress(),
'override_merchant_preferences' => $this->getMerchantPreferences(),
'override_charge_models' => $this->getChargeModel(),
);
return $data;
}
/**
* Get transaction endpoint.
*
* Subscriptions are created using the /billing-agreements resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements';
}
protected function createResponse($data, $statusCode)
{
return $this->response = new RestAuthorizeResponse($this, $data, $statusCode);
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* PayPal REST Delete Card Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Delete Card Request
*
* PayPal offers merchants a /vault API to store sensitive details
* like credit card related details.
*
* You can currently use the /vault API to store credit card details
* 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.
*
* Direct credit card payment and related features are restricted in
* some countries.
* As of January 2015 these transactions are only supported in the UK
* and in the USA.
*
* Example. This example assumes that the card has already been created
* using a RestCreateCardRequest call and that the card ID has been stored
* in $card_id. See RestCreateCardRequest for the details of the first
* part of this process.
*
* <code>
* $transaction = $gateway->deleteCard();
* $transaction->setCardReference($card_id);
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Gateway deleteCard was successful.\n";
* } else {
* echo "Gateway deleteCard failed.\n";
* }
* </code>
*
* @link https://developer.paypal.com/docs/api/#vault
* @link https://developer.paypal.com/docs/api/#delete-a-stored-credit-card
* @link http://bit.ly/1wUQ33R
* @see RestCreateCardRequest
*/
class RestDeleteCardRequest extends AbstractRestRequest
{
public function getHttpMethod()
{
return 'DELETE';
}
public function getData()
{
$this->validate('cardReference');
return array();
}
public function getEndpoint()
{
return parent::getEndpoint() . '/vault/credit-cards/' . $this->getCardReference();
}
}

View File

@@ -0,0 +1,55 @@
<?php
/**
* PayPal REST Fetch Purchase Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Fetch Purchase Request
*
* Use this call to get details about payments that have not completed, such
* as payments that are created and approved, or if a payment has failed.
*
* ### Example
*
* See RestPurchaseRequest for the first part of this example transaction:
*
* <code>
* // Fetch the transaction so that details can be found for refund, etc.
* $transaction = $gateway->fetchPurchase();
* $transaction->setTransactionReference($sale_id);
* $response = $transaction->send();
* $data = $response->getData();
* echo "Gateway fetchTransaction response data == " . print_r($data, true) . "\n";
* </code>
*
* @see RestPurchaseRequest
* @link https://developer.paypal.com/docs/api/#look-up-a-payment-resource
*/
class RestFetchPurchaseRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
return array();
}
/**
* Get HTTP Method.
*
* The HTTP method for fetchTransaction requests must be GET.
* Using POST results in an error 500 from PayPal.
*
* @return string
*/
protected function getHttpMethod()
{
return 'GET';
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/payment/' . $this->getTransactionReference();
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* PayPal REST Fetch Transaction Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Fetch Transaction Request
*
* To get details about completed payments (sale transaction) created by a payment request
* or to refund a direct sale transaction, PayPal provides the /sale resource and related
* sub-resources.
*
* Example -- note this example assumes that the purchase has been successful
* and that the transaction ID returned from the purchase is held in $sale_id.
* See RestPurchaseRequest for the first part of this example transaction:
*
* <code>
* // Fetch the transaction so that details can be found for refund, etc.
* $transaction = $gateway->fetchTransaction();
* $transaction->setTransactionReference($sale_id);
* $response = $transaction->send();
* $data = $response->getData();
* echo "Gateway fetchTransaction response data == " . print_r($data, true) . "\n";
* </code>
*
* @see RestPurchaseRequest
* @link https://developer.paypal.com/docs/api/#sale-transactions
*/
class RestFetchTransactionRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
return array();
}
/**
* Get HTTP Method.
*
* The HTTP method for fetchTransaction requests must be GET.
* Using POST results in an error 500 from PayPal.
*
* @return string
*/
protected function getHttpMethod()
{
return 'GET';
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/sale/' . $this->getTransactionReference();
}
}

View File

@@ -0,0 +1,242 @@
<?php
/**
* PayPal REST List Plans Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST List Plans Request
*
* Use this call to get a list of plans in any state (CREATED, ACTIVE, etc.).
* The plans returned are the plans made by the merchant making the call.
*
*
* ### Example
*
* #### Initialize Gateway
*
* <code>
* // Create a gateway for the PayPal RestGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
* </code>
*
* #### List all plans that have state CREATED
* <code>
*
* // List all billing plans
* $transaction = $gateway->listPlan([
* 'state' => CREATED,
* ]);
* $response = $transaction->send();
* $data = $response->getData();
* echo "Gateway listPlan response data == " . print_r($data, true) . "\n";
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v -X GET https://api.sandbox.paypal.com/v1/payments/billing-plans?page_size=3&status=ACTIVE&page=1\
* -H "Content-Type:application/json" \
* -H "Authorization: Bearer Access-Token"
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "total_items": "166",
* "total_pages": "83",
* "plans": [
* {
* "id": "P-7DC96732KA7763723UOPKETA",
* "state": "ACTIVE",
* "name": "Plan with Regular and Trial Payment Definitions",
* "description": "Plan with regular and trial billing payment definitions.",
* "type": "FIXED",
* "create_time": "2017-08-22T04:41:52.836Z",
* "update_time": "2017-08-22T04:41:53.169Z",
* "links": [
* {
* "href": "https://api.sandbox.paypal.com//v1/payments/billing-plans/P-7DC96732KA7763723UOPKETA",
* "rel": "self",
* "method": "GET"
* }
* ]
* },
* {
* "id": "P-1TV69435N82273154UPWDU4I",
* "state": "ACTIVE",
* "name": "Plan with Regular Payment Definition",
* "description": "Plan with one regular payment definition, minimal merchant preferences, and no shipping fee",
* "type": "INFINITE",
* "create_time": "2017-08-22T04:41:55.623Z",
* "update_time": "2017-08-22T04:41:56.055Z",
* "links": [
* {
* "href": "https://api.sandbox.paypal.com//v1/payments/billing-plans/P-1TV69435N82273154UPWDU4I",
* "rel": "self",
* "method": "GET"
* }
* ]
* }
* ],
* "links": [
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-plans?page_size=2&page=1&start=3&status=active",
* "rel": "start",
* "method": "GET"
* },
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-plans?page_size=2&page=0&status=active",
* "rel": "previous_page",
* "method": "GET"
* },
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-plans?page_size=2&page=2&status=active",
* "rel": "next_page",
* "method": "GET"
* },
* {
* "href": "https://api.sandbox.paypal.com/v1/payments/billing-plans?page_size=2&page=82&status=active",
* "rel": "last",
* "method": "GET"
* }
* ]
* }
*
* </code>
*
* @link https://developer.paypal.com/docs/api/payments.billing-plans#plan_list
*/
class RestListPlanRequest extends AbstractRestRequest
{
/**
*
* Get the request page
*
* @return integer
*/
public function getPage()
{
return $this->getParameter('page');
}
/**
* Set the request page
*
* @param integer $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setPage($value)
{
return $this->setParameter('page', $value);
}
/**
* Get the request status
*
* @return string
*/
public function getStatus()
{
return $this->getParameter('status');
}
/**
* Set the request status
*
* @param string $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setStatus($value)
{
return $this->setParameter('status', $value);
}
/**
* Get the request page size
*
* @return string
*/
public function getPageSize()
{
return $this->getParameter('pageSize');
}
/**
* Set the request page size
*
* @param string $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setPageSize($value)
{
return $this->setParameter('pageSize', $value);
}
/**
* Get the request total required
*
* @return string
*/
public function getTotalRequired()
{
return $this->getParameter('totalRequired');
}
/**
* Set the request total required
*
* @param string $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setTotalRequired($value)
{
return $this->setParameter('totalRequired', $value);
}
public function getData()
{
return array(
'page' => $this->getPage(),
'status' => $this->getStatus(),
'page_size' => $this->getPageSize(),
'total_required' => $this->getTotalRequired()
);
}
/**
* Get HTTP Method.
*
* The HTTP method for list plans requests must be GET.
*
* @return string
*/
protected function getHttpMethod()
{
return 'GET';
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-plans';
}
}

View File

@@ -0,0 +1,282 @@
<?php
/**
* PayPal REST List Purchase Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST List Purchase Request
*
* Use this call to get a list of payments in any state (created, approved,
* failed, etc.). The payments returned are the payments made to the merchant
* making the call.
*
* ### Example
*
* See RestPurchaseRequest for the first part of this example transaction:
*
* <code>
* // Make some DateTimes for start and end times
* $start_time = new \DateTime('yesterday');
* $end_time = new \DateTime('now');
*
* // List the transaction so that details can be found for refund, etc.
* $transaction = $gateway->listPurchase(
* 'startTime' => $start_time,
* 'endTime => $end_time
* );
* $response = $transaction->send();
* $data = $response->getData();
* echo "Gateway listPurchase response data == " . print_r($data, true) . "\n";
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v -X GET https://api.sandbox.paypal.com/v1/payments/payment?
* sort_order=asc&sort_by=update_time \
* -H "Content-Type:application/json" \
* -H "Authorization: Bearer <Access-Token>"
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "payments": [
* {
* "id": "PAY-4D099447DD202993VKEFMRJQ",
* "create_time": "2013-01-31T19:40:22Z",
* "update_time": "2013-01-31T19:40:24Z",
* "state": "approved",
* "intent": "sale",
* "payer": {
* "payment_method": "credit_card",
* "funding_instruments": [
* {
* "credit_card": {
* "type": "visa",
* "number": "xxxxxxxxxxxx0331",
* "expire_month": "10",
* "expire_year": "2018",
* "first_name": "Betsy",
* "last_name": "Buyer",
* "billing_address": {
* "line1": "111 First Street",
* "city": "Saratoga",
* "state": "CA",
* "postal_code": "95070",
* "country_code": "US"
* }
* }
* }
* ]
* },
* "transactions": [
* {
* "amount": {
* "total": "110.54",
* "currency": "USD"
* },
* "description": "This is the payment transaction description.",
* "related_resources": [
* {
* "sale": {
* "id": "1D971400A7097562W",
* "create_time": "2013-01-31T19:40:23Z",
* "update_time": "2013-01-31T19:40:25Z",
* "state": "completed",
* "amount": {
* "total": "110.54",
* "currency": "USD"
* },
* "parent_payment": "PAY-4D099447DD202993VKEFMRJQ",
* "links": [
* {
* "href":
* "https://api.sandbox.paypal.com/v1/payments/sale/1D971400A7097562W",
* "rel": "self",
* "method": "GET"
* },
* {
* "href":
* "https://api.sandbox.paypal.com/v1/payments/sale/1D971400A7097562W/refund",
* "rel": "refund",
* "method": "POST"
* },
* {
* "href":
* "https://api.sandbox.paypal.com/v1/payments/payment/PAY-4D099447DD202993VKEFMRJQ",
* "rel": "parent_payment",
* "method": "GET"
* }
* ]
* }
* }
* ]
* }
* ],
* "links": [
* {
* "href":
* "https://api.sandbox.paypal.com/v1/payments/payment/PAY-4D099447DD202993VKEFMRJQ",
* "rel": "self",
* "method": "GET"
* }
* ]
* }
* ]
* }
* </code>
*
* @see RestPurchaseRequest
* @link https://developer.paypal.com/docs/api/#list-payment-resources
*/
class RestListPurchaseRequest extends AbstractRestRequest
{
/**
* Get the request count
*
* @return integer
*/
public function getCount()
{
return $this->getParameter('count');
}
/**
* Set the request count
*
* @param integer $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setCount($value)
{
return $this->setParameter('count', $value);
}
/**
* Get the request startId
*
* @return string
*/
public function getStartId()
{
return $this->getParameter('startId');
}
/**
* Set the request startId
*
* @param string $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setStartId($value)
{
return $this->setParameter('startId', $value);
}
/**
* Get the request startIndex
*
* @return integer
*/
public function getStartIndex()
{
return $this->getParameter('startIndex');
}
/**
* Set the request startIndex
*
* @param integer $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setStartIndex($value)
{
return $this->setParameter('startIndex', $value);
}
/**
* Get the request startTime
*
* @return string
*/
public function getStartTime()
{
return $this->getParameter('startTime');
}
/**
* Set the request startTime
*
* @param string|\DateTime $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setStartTime($value)
{
if ($value instanceof \DateTime) {
$value->setTimezone(new \DateTimeZone('UTC'));
$value = $value->format('Y-m-d\TH:i:s\Z');
}
return $this->setParameter('startTime', $value);
}
/**
* Get the request endTime
*
* @return string
*/
public function getEndTime()
{
return $this->getParameter('endTime');
}
/**
* Set the request endTime
*
* @param string|\DateTime $value
* @return AbstractRestRequest provides a fluent interface.
*/
public function setEndTime($value)
{
if ($value instanceof \DateTime) {
$value->setTimezone(new \DateTimeZone('UTC'));
$value = $value->format('Y-m-d\TH:i:s\Z');
}
return $this->setParameter('endTime', $value);
}
public function getData()
{
return array(
'count' => $this->getCount(),
'start_id' => $this->getStartId(),
'start_index' => $this->getStartIndex(),
'start_time' => $this->getStartTime(),
'end_time' => $this->getEndTime(),
);
}
/**
* Get HTTP Method.
*
* The HTTP method for listPurchase requests must be GET.
*
* @return string
*/
protected function getHttpMethod()
{
return 'GET';
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/payment';
}
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* PayPal REST Purchase Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Purchase Request
*
* PayPal provides various payment related operations using
* the /payment resource and related sub-resources. Use payment
* for direct credit card payments and PayPal account payments.
* You can also use sub-resources to get payment related details.
*
* Note that a PayPal Purchase Request looks exactly like a PayPal
* Authorize request except that the 'intent' is set to 'sale' for
* immediate payment. This class takes advantage of that by
* extending the RestAuthorizeRequest class and simply over-riding
* the getData() function to set the intent to sale.
*
* ### Example
*
* #### Initialize Gateway
*
* <code>
* // Create a gateway for the PayPal RestGateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
* </code>
*
* #### 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.
*
* <code>
* // Create a credit card object
* // DO NOT USE THESE CARD VALUES -- substitute your own
* // see the documentation in the class header.
* $card = new CreditCard(array(
* 'firstName' => 'Example',
* 'lastName' => 'User',
* 'number' => '4111111111111111',
* 'expiryMonth' => '01',
* 'expiryYear' => '2020',
* 'cvv' => '123',
* 'billingAddress1' => '1 Scrubby Creek Road',
* 'billingCountry' => 'AU',
* 'billingCity' => 'Scrubby Creek',
* 'billingPostcode' => '4999',
* 'billingState' => 'QLD',
* ));
*
* // 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";
* }
* </code>
*
* Direct credit card payment and related features are restricted in
* some countries.
* 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.
*
* <code>
* $transaction = MyClass::saveTransaction($some_data);
* $txn_id = $transaction->getId();
* </code>
*
* Step 2 is to send the purchase request.
*
* <code>
* // 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";
* }
* </code>
*
* 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.
*
* <code>
* 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());
* }
* </code>
*
* 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.
*
* <code>
* $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.
* }
* </code>
*
* #### 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
*/
class RestPurchaseRequest extends RestAuthorizeRequest
{
public function getData()
{
$data = parent::getData();
$data['intent'] = 'sale';
return $data;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* PayPal REST Reactivate Subscription Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Reactivate Subscription Request
*
* Use this call to reactivate an agreement.
*
* ### Request Data
*
* Pass the agreement id in the URI of a POST call. Also include a description,
* which is the reason for reactivating the subscription.
*
* ### Example
*
* To create the agreement, see the code example in RestCreateSubscriptionRequest.
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a reactivate subscription transaction on the gateway
* $transaction = $gateway->reactivateSubscription(array(
* 'transactionReference' => $subscription_id,
* 'description' => "Reactivating the agreement.",
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Reactivate Subscription transaction was successful!\n";
* }
* </code>
*
* Note that the subscription_id that you get from calling the response's
* getTransactionReference() method at the end of the completeSubscription
* call will be different to the one that you got after calling the response's
* getTransactionReference() method at the end of the createSubscription
* call. The one that you get from completeSubscription is the correct
* one to use going forwards (e.g. for cancelling or updating the subscription).
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/re-activate \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{
* "note": "Reactivating the agreement."
* }'
* </code>
*
* @link https://developer.paypal.com/docs/api/#reactivate-an-agreement
* @see RestCreateSubscriptionRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestReactivateSubscriptionRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference', 'description');
$data = array(
'note' => $this->getDescription(),
);
return $data;
}
/**
* Get transaction endpoint.
*
* Subscriptions are executed using the /billing-agreements resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements/' .
$this->getTransactionReference() . '/re-activate';
}
}

View File

@@ -0,0 +1,36 @@
<?php
/**
* PayPal REST Refund Captured Payment Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Refund Captured Payment Request
*
* Use this call to refund a captured payment.
*
* @link https://developer.paypal.com/docs/api/#refund-a-captured-payment
* @see RestAuthorizeRequest
* @see RestCaptureRequest
*/
class RestRefundCaptureRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
return array(
'amount' => array(
'currency' => $this->getCurrency(),
'total' => $this->getAmount(),
),
'description' => $this->getDescription(),
);
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/capture/' . $this->getTransactionReference() . '/refund';
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* PayPal REST Refund Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Refund Request
*
* To get details about completed payments (sale transaction) created by a payment request
* or to refund a direct sale transaction, PayPal provides the /sale resource and related
* sub-resources.
*
* TODO: There might be a problem here, in that refunding a capture requires a different URL.
*
* TODO: Yes I know. The gateway doesn't yet support looking up or refunding captured
* transactions. That will require adding additional message classes because the URLs
* are all different.
*
* A non-zero amount can be provided for the refund using setAmount(), if this is not
* provided (or is zero) then a full refund is made.
*
* Example -- note this example assumes that the purchase has been successful
* and that the transaction ID returned from the purchase is held in $sale_id.
* See RestPurchaseRequest for the first part of this example transaction:
*
* <code>
* $transaction = $gateway->refund(array(
* 'amount' => '10.00',
* 'currency' => 'AUD',
* ));
* $transaction->setTransactionReference($sale_id);
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Refund transaction was successful!\n";
* $data = $response->getData();
* echo "Gateway refund response data == " . print_r($data, true) . "\n";
* }
* </code>
*
* ### Known Issues
*
* PayPal subscription payments cannot be refunded. PayPal is working on this functionality
* for their future API release. In order to refund a PayPal subscription payment, you will
* need to use the PayPal web interface to refund it manually.
*
* @see RestPurchaseRequest
*/
class RestRefundRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
if ($this->getAmount() > 0) {
return array(
'amount' => array(
'currency' => $this->getCurrency(),
'total' => $this->getAmount(),
),
'description' => $this->getDescription(),
);
} else {
return new \stdClass();
}
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/sale/' . $this->getTransactionReference() . '/refund';
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* PayPal REST Response
*/
namespace Omnipay\PayPal\Message;
use Omnipay\Common\Message\AbstractResponse;
use Omnipay\Common\Message\RequestInterface;
/**
* PayPal REST Response
*/
class RestResponse extends AbstractResponse
{
protected $statusCode;
public function __construct(RequestInterface $request, $data, $statusCode = 200)
{
parent::__construct($request, $data);
$this->statusCode = $statusCode;
}
public function isSuccessful()
{
return empty($this->data['error']) && $this->getCode() < 400;
}
public function getTransactionReference()
{
// This is usually correct for payments, authorizations, etc
if (!empty($this->data['transactions']) && !empty($this->data['transactions'][0]['related_resources'])) {
foreach (array('sale', 'authorization') as $type) {
if (!empty($this->data['transactions'][0]['related_resources'][0][$type])) {
return $this->data['transactions'][0]['related_resources'][0][$type]['id'];
}
}
}
// This is a fallback, but is correct for fetch transaction and possibly others
if (!empty($this->data['id'])) {
return $this->data['id'];
}
return null;
}
public function getMessage()
{
if (isset($this->data['error_description'])) {
return $this->data['error_description'];
}
if (isset($this->data['message'])) {
return $this->data['message'];
}
return null;
}
public function getCode()
{
return $this->statusCode;
}
public function getCardReference()
{
if (isset($this->data['id'])) {
return $this->data['id'];
}
}
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* PayPal REST Search Transaction Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Search Transaction Request
*
* Use this call to search for the transactions within a billing agreement.
* Note that this is not a generic transaction search function -- for that
* see RestListPurchaseRequest. It only searches for transactions within
* a billing agreement.
*
* This should be used on a regular basis to determine the success / failure
* state of transactions on active billing agreements.
*
* ### Example
*
* <code>
* // List the transactions for a billing agreement.
* $transaction = $gateway->listPurchase();
* $response = $transaction->send();
* $data = $response->getData();
* echo "Gateway listPurchase response data == " . print_r($data, true) . "\n";
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v GET https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/transactions \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>'
* </code>
*
* ### Response Sample
*
* This is from the PayPal web site:
*
* <code>
* {
* "agreement_transaction_list": [
* {
* "transaction_id": "I-0LN988D3JACS",
* "status": "Created",
* "transaction_type": "Recurring Payment",
* "payer_email": "bbuyer@example.com",
* "payer_name": "Betsy Buyer",
* "time_stamp": "2014-06-09T09:29:36Z",
* "time_zone": "GMT"
* },
* {
* "transaction_id": "928415314Y5640008",
* "status": "Completed",
* "transaction_type": "Recurring Payment",
* "amount": {
* "currency": "USD",
* "value": "1.00"
* },
* "fee_amount": {
* "currency": "USD",
* "value": "-0.33"
* },
* "net_amount": {
* "currency": "USD",
* "value": "0.67"
* },
* "payer_email": "bbuyer@example.com",
* "payer_name": "Betsy Buyer",
* "time_stamp": "2014-06-09T09:42:47Z",
* "time_zone": "GMT"
* },
* {
* "transaction_id": "I-0LN988D3JACS",
* "status": "Suspended",
* "transaction_type": "Recurring Payment",
* "payer_email": "bbuyer@example.com",
* "payer_name": "Betsy Buyer",
* "time_stamp": "2014-06-09T11:18:34Z",
* "time_zone": "GMT"
* },
* {
* "transaction_id": "I-0LN988D3JACS",
* "status": "Reactivated",
* "transaction_type": "Recurring Payment",
* "payer_email": "bbuyer@example.com",
* "payer_name": "Betsy Buyer",
* "time_stamp": "2014-06-09T11:18:48Z",
* "time_zone": "GMT"
* }
* ]
* }
* </code>
*
* ### Known Issues
*
* PayPal subscription payments cannot be refunded. PayPal is working on this functionality
* for their future API release. In order to refund a PayPal subscription payment, you will
* need to use the PayPal web interface to refund it manually.
*
* @see RestCreateSubscriptionRequest
* @link https://developer.paypal.com/docs/api/#search-for-transactions
*/
class RestSearchTransactionRequest extends AbstractRestRequest
{
/**
* Get the agreement ID
*
* @return string
*/
public function getAgreementId()
{
return $this->getParameter('agreementId');
}
/**
* Set the agreement ID
*
* @param string $value
* @return RestSearchTransactionRequest provides a fluent interface.
*/
public function setAgreementId($value)
{
return $this->setParameter('agreementId', $value);
}
/**
* Get the request startDate
*
* @return string
*/
public function getStartDate()
{
return $this->getParameter('startDate');
}
/**
* Set the request startDate
*
* @param string|DateTime $value
* @return RestSearchTransactionRequest provides a fluent interface.
*/
public function setStartDate($value)
{
return $this->setParameter('startDate', is_string($value) ? new \DateTime($value) : $value);
}
/**
* Get the request endDate
*
* @return string
*/
public function getEndDate()
{
return $this->getParameter('endDate');
}
/**
* Set the request endDate
*
* @param string|DateTime $value
* @return RestSearchTransactionRequest provides a fluent interface.
*/
public function setEndDate($value)
{
return $this->setParameter('endDate', is_string($value) ? new \DateTime($value) : $value);
}
public function getData()
{
$this->validate('agreementId', 'startDate', 'endDate');
return array(
'start_date' => $this->getStartDate()->format('Y-m-d'),
'end_date' => $this->getEndDate()->format('Y-m-d'),
);
}
/**
* Get HTTP Method.
*
* The HTTP method for searchTransaction requests must be GET.
*
* @return string
*/
protected function getHttpMethod()
{
return 'GET';
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements/' .
$this->getAgreementId() . '/transactions';
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* PayPal REST Suspend Subscription Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Suspend Subscription Request
*
* Use this call to suspend an agreement.
*
* ### Request Data
*
* Pass the agreement id in the URI of a POST call. Also include a description,
* which is the reason for suspending the subscription.
*
* ### Example
*
* To create the agreement, see the code example in RestCreateSubscriptionRequest.
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Do a suspend subscription transaction on the gateway
* $transaction = $gateway->suspendSubscription(array(
* 'transactionReference' => $subscription_id,
* 'description' => "Suspending the agreement.",
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Suspend Subscription transaction was successful!\n";
* }
* </code>
*
* Note that the subscription_id that you get from calling the response's
* getTransactionReference() method at the end of the completeSubscription
* call will be different to the one that you got after calling the response's
* getTransactionReference() method at the end of the createSubscription
* call. The one that you get from completeSubscription is the correct
* one to use going forwards (e.g. for cancelling or updating the subscription).
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v POST https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-0LN988D3JACS/suspend \
* -H 'Content-Type:application/json' \
* -H 'Authorization: Bearer <Access-Token>' \
* -d '{
* "note": "Suspending the agreement."
* }'
* </code>
*
* @link https://developer.paypal.com/docs/api/#suspend-an-agreement
* @see RestCreateSubscriptionRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestSuspendSubscriptionRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference', 'description');
$data = array(
'note' => $this->getDescription(),
);
return $data;
}
/**
* Get transaction endpoint.
*
* Subscriptions are executed using the /billing-agreements resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-agreements/' .
$this->getTransactionReference() . '/suspend';
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* PayPal REST Token Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Token Request
*
* With each API call, youll need to set request headers, including
* an OAuth 2.0 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.
*
* @link https://developer.paypal.com/docs/integration/direct/make-your-first-call/
* @link https://developer.paypal.com/docs/api/#authentication--headers
*/
class RestTokenRequest extends AbstractRestRequest
{
public function getData()
{
return array('grant_type' => 'client_credentials');
}
protected function getEndpoint()
{
return parent::getEndpoint() . '/oauth2/token';
}
public function sendData($data)
{
$body = $data ? http_build_query($data, '', '&') : null;
$httpResponse = $this->httpClient->request(
$this->getHttpMethod(),
$this->getEndpoint(),
array(
'Accept' => 'application/json',
'Authorization' => 'Basic ' . base64_encode("{$this->getClientId()}:{$this->getSecret()}"),
),
$body
);
// Empty response body should be parsed also as and empty array
$body = (string) $httpResponse->getBody()->getContents();
$jsonToArrayResponse = !empty($body) ? json_decode($body, true) : array();
return $this->response = new RestResponse($this, $jsonToArrayResponse, $httpResponse->getStatusCode());
}
}

View File

@@ -0,0 +1,127 @@
<?php
/**
* PayPal REST Update Plan Request
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Update Plan Request
*
* You can update the information for an existing billing plan. The state
* of a plan must be active before a billing agreement is created.
*
* ### Request Data
*
* Pass the billing plan id in the URI of a PATCH call, including the replace
* operation in the body. Other operations in the patch_request object will
* throw validation exceptions.
*
* ### Example
*
* To create the billing plan, see the code example in RestCreatePlanRequest.
*
* <code>
* // Create a gateway for the PayPal REST Gateway
* // (routes to GatewayFactory::create)
* $gateway = Omnipay::create('PayPal_Rest');
*
* // Initialise the gateway
* $gateway->initialize(array(
* 'clientId' => 'MyPayPalClientId',
* 'secret' => 'MyPayPalSecret',
* 'testMode' => true, // Or false when you are ready for live transactions
* ));
*
* // Update the billing plan
* $transaction = $gateway->updatePlan(array(
* 'transactionReference' => $plan_id,
* 'state' => $gateway::BILLING_PLAN_STATE_ACTIVE,
* ));
* $response = $transaction->send();
* if ($response->isSuccessful()) {
* echo "Update Plan transaction was successful!\n";
* }
* </code>
*
* ### Request Sample
*
* This is from the PayPal web site:
*
* <code>
* curl -v -k -X PATCH 'https://api.sandbox.paypal.com/v1/payments/billing-plans/P-94458432VR012762KRWBZEUA' \
* -H "Content-Type: application/json" \
* -H "Authorization: Bearer <Access-Token>" \
* -d '[
* {
* "path": "/",
* "value": {
* "state": "ACTIVE"
* },
* "op": "replace"
* }
* ]'
* </code>
*
* ### Response
*
* Returns the HTTP status of 200 if the call is successful.
*
* @link https://developer.paypal.com/docs/api/#update-a-plan
* @see RestCreateSubscriptionRequest
* @see Omnipay\PayPal\RestGateway
*/
class RestUpdatePlanRequest extends AbstractRestRequest
{
/**
* Get the plan state
*
* @return string
*/
public function getState()
{
return $this->getParameter('state');
}
/**
* Set the plan state
*
* @param string $value
* @return RestUpdatePlanRequest provides a fluent interface.
*/
public function setState($value)
{
return $this->setParameter('state', $value);
}
public function getData()
{
$this->validate('transactionReference', 'state');
$data = array(array(
'path' => '/',
'value' => array(
'state' => $this->getState(),
),
'op' => 'replace'
));
return $data;
}
/**
* Get transaction endpoint.
*
* Billing plans are managed using the /billing-plans resource.
*
* @return string
*/
protected function getEndpoint()
{
return parent::getEndpoint() . '/payments/billing-plans/' . $this->getTransactionReference();
}
protected function getHttpMethod()
{
return 'PATCH';
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* PayPal REST Void an authorization
*/
namespace Omnipay\PayPal\Message;
/**
* PayPal REST Void an authorization
*
* Use this call to void a previously authorized payment.
* Note: A fully captured authorization cannot be voided.
*
* @link https://developer.paypal.com/docs/api/#void-an-authorization
* @see RestAuthorizeRequest
*/
class RestVoidRequest extends AbstractRestRequest
{
public function getData()
{
$this->validate('transactionReference');
}
public function getEndpoint()
{
return parent::getEndpoint() . '/payments/authorization/' . $this->getTransactionReference() . '/void';
}
}