A CakePHP plugin to interact with Paypal's "classic" and new REST APIs.
- CakePHP 2.x
- A PayPal Website Payments Pro account
[Manual]
- Download this: http://github.com/robmcvey/cakephp-paypal/zipball/master
- Unzip that download.
- Copy the resulting folder to
app/Plugin
- Rename the folder you just copied to
Paypal
[GIT Submodule]
In your app directory type:
git submodule add -b master git://github.com/robmcvey/cakephp-paypal.git Plugin/Paypal
git submodule init
git submodule update
[GIT Clone]
In your Plugin
directory type:
git clone -b master git://github.com/robmcvey/cakephp-paypal.git Paypal
Make sure the plugin is loaded in app/Config/bootstrap.php
.
CakePlugin::load('Paypal');
Create an instance of the class with your PayPal credentials. For testing purposes, ensure sandboxMode
is set to true
.
App::uses('Paypal', 'Paypal.Lib');
$this->Paypal = new Paypal(array(
'sandboxMode' => true,
'nvpUsername' => '{username}',
'nvpPassword' => '{password}',
'nvpSignature' => '{signature}'
));
Create an order(s) in the following format. setExpressCheckout
will return a string URL to redirect the customer to.
$order = array(
'description' => 'Your purchase with Acme clothes store',
'currency' => 'GBP',
'return' => 'https://www.my-amazing-clothes-store.com/review-paypal.php',
'cancel' => 'https://www.my-amazing-clothes-store.com/checkout.php',
'custom' => 'bingbong',
'items' => array(
0 => array(
'name' => 'Blue shoes',
'description' => 'A pair of really great blue shoes',
'tax' => 2.00,
'shipping' => 0.00,
'subtotal' => 8.00,
),
1 => array(
'name' => 'Red trousers',
'description' => 'Tight pair of red pants, look good with a hat.',
'tax' => 2.00,
'shipping' => 2.00,
'subtotal' => 6.00
),
)
);
try {
$this->Paypal->setExpressCheckout($order);
} catch (Exception $e) {
// $e->getMessage();
}
Once the customer has returned to your site (see return
URL above) you can request their details with the token returned from the setExpressCheckout
method.
try {
$this->Paypal->getExpressCheckoutDetails($token);
} catch (Exception $e) {
// $e->getMessage();
}
Complete the transaction using the same order details. The $token
and $payerId
will be returned from the setExpressCheckout
method.
$order = array(
'description' => 'Your purchase with Acme clothes store',
'currency' => 'GBP',
'return' => 'https://www.my-amazing-clothes-store.com/review-paypal.php',
'cancel' => 'https://www.my-amazing-clothes-store.com/checkout.php',
'custom' => 'bingbong',
'items' => array(
0 => array(
'name' => 'Blue shoes',
'description' => 'A pair of really great blue shoes',
'tax' => 2.00,
'shipping' => 0.00,
'subtotal' => 8.00,
),
1 => array(
'name' => 'Red trousers',
'description' => 'Tight pair of red pants, look good with a hat.',
'tax' => 2.00,
'shipping' => 2.00,
'subtotal' => 6.00
),
)
);
try {
$this->Paypal->doExpressCheckoutPayment($order, $token, $payerId);
} catch (Exception $e) {
// $e->getMessage();
}
Charge a credit card. Ensure you are using SSL and following PCI compliance guidelines.
$payment = array(
'amount' => 30.00,
'card' => '4008 0687 0641 8697', // This is a sandbox CC
'expiry' => array(
'M' => '2',
'Y' => '2016',
),
'cvv' => '321',
'currency' => 'USD' // Defaults to GBP if not provided
);
try {
$this->Paypal->doDirectPayment($payment);
} catch (Exception $e) {
// $e->getMessage();
}
Refund a transaction. Transactions can only be refunded up to 60 days after the completion date.
$refund = array(
'transactionId' => '96L684679W100181R' // Original PayPal Transcation ID
'type' => 'Partial', // Full, Partial, ExternalDispute, Other
'amount' => 30.00, // Amount to refund, only required if Refund Type is Partial
'note' => 'Refund because we are nice', // Optional note to customer
'reference' => 'abc123', // Optional internal reference
'currency' => 'USD' // Defaults to GBP if not provided
);
try {
$this->Paypal->refundTransaction($refund);
} catch (Exception $e) {
// $e->getMessage();
}
Create an instance of the class with your PayPal credentials, including your client ID and secret key For testing purposes, ensure sandboxMode
is set to true
.
App::uses('Paypal', 'Paypal.Lib');
$this->Paypal = new Paypal(array(
'sandboxMode' => true,
'nvpUsername' => '{username}',
'nvpPassword' => '{password}',
'nvpSignature' => '{signature}',
'oAuthClientId' => '{client ID}',
'oAuthSecret' => '{secret key}',
));
You can store a customer's card in the vault, in return for a token which can be used for future transactions.
$creditCard = array(
'payer_id' => 186,
'type' => 'visa',
'card' => 'xxxxxxxxxxxx8697',
'cvv2' => 232,
'expiry' => array(
'M' => '2',
'Y' => '2018',
),
'first_name' => 'Joe',
'last_name' => 'Shopper'
);
try {
$this->Paypal->storeCreditCard($creditCard);
} catch (Exception $e) {
// $e->getMessage();
}
Once a card is stored in the vault, you can make a charge(s) on that card using the token issued when it was first stored.
$cardPayment = array(
'intent' => 'sale',
'payer' => array(
'payment_method' => 'credit_card',
'funding_instruments' => array(
0 => array(
'credit_card_token' => array(
'credit_card_id' => 'CARD-39N7854321M2DDC2',
'payer_id' => '186'
)
)
)
),
'transactions' => array(
0 => array(
'amount' => array(
'total' => '0.60',
'currency' => 'GBP',
"details" => array(
"subtotal" => "0.50",
"tax" => "0.10",
"shipping" => "0.00"
)
),
'description' => 'This is test payment'
)
)
);
try {
$this->Paypal->chargeStoredCard($cardPayment);
} catch (Exception $e) {
// $e->getMessage();
}
Create an instance of the class with your PayPal credentials, including your Adaptive App ID and Adaptive username. For testing purposes, ensure sandboxMode
is set to true
.
App::uses('Paypal', 'Paypal.Lib');
$this->Paypal = new Paypal(array(
'sandboxMode' => true,
'nvpUsername' => '{username}',
'nvpPassword' => '{password}',
'nvpSignature' => '{signature}',
'adaptiveAppID' => '{adaptive app id}',
'adaptiveUserID' => '{adaptive user id}'
));
The GetVerifiedStatus API operation lets you determine whether the specified PayPal account's status is verified or unverified.
try {
$this->Paypal->getVerifiedStatus('[email protected]')
} catch (Exception $e) {
// $e->getMessage();
}