Skip to content

Commit

Permalink
Add refund function
Browse files Browse the repository at this point in the history
  • Loading branch information
hakito committed Sep 18, 2022
1 parent 2beb381 commit 6be8643
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 2 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ To receive the payment notifications in your app the Plugin expects 3 event hand

```php

$eventManager = TableRegistry::getTableLocator()->get('PayPal.PayPalPayments')->getEventManager();
$payPalPayments = TableRegistry::getTableLocator()->get('PayPal.PayPalPayments');
$eventManager = $payPalPayments->getEventManager();
$eventManager->setEventList(new EventList());

// Will be called just after PayPal redirects the customer
Expand All @@ -111,6 +112,15 @@ function($event, $remittanceIdentifier) {});

```

To issue a full refund lookup the payment and issue the refund.

```php

$payPalPayment = $payPalPayments->findByRemittanceIdentifier($remittanceIdentifier);
$payPalPayments->refundPayment($payPalPayment);

```

## Remarks

The current implementation does not support automatic handling payments in pending state.
36 changes: 36 additions & 0 deletions src/Model/Table/PayPalPaymentsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
use Cake\Routing\Router;
use Cake\Utility\Security;
use DateTime;
use PayPal\Api\DetailedRefund;
use PayPal\Api\Payment;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\RedirectUrls;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\RelatedResources;
use PayPal\Api\Sale;
use PayPal\Api\Transaction;
use PayPal\Model\Entity\PayPalPayment;

Expand Down Expand Up @@ -165,6 +169,33 @@ public function execute(int $id, ?string $payerId)
}
}

/**
* Performs a full refund.
* @return bool|DetailedRefund false when payment not found
*/
public function refund(int $id)
{
/** @var PayPalPayment */
$payPalPayment = $this->findById($id)->first();
if (empty($payPalPayment))
return false;

return $this->refundPayment($payPalPayment);
}

/**
* Performs a full refund
* @return DetailedRefund
*/
public function refundPayment(PayPalPayment $payPalPayment)
{
$ppReq = $this->ApiGet($payPalPayment->payment_id);
$transactions = $ppReq->getTransactions();
$relatedResources = $this->getRelatedResources($transactions);
$sale = $relatedResources->getSale();
return $this->ApiRefundSale($sale);
}

public static function getApiContext(): ApiContext
{
$config = Configure::read('PayPal');
Expand Down Expand Up @@ -220,6 +251,11 @@ protected function ApiGet($paymentId): Payment
return \PayPal\Api\Payment::get($paymentId, self::getApiContext());
}

protected function ApiRefundSale(Sale $sale): DetailedRefund
{
return $sale->refundSale(new RefundRequest(), self::getApiContext());
}

private static function getCredentials(): array
{
$config = Configure::read('PayPal');
Expand Down
31 changes: 30 additions & 1 deletion tests/TestCase/Model/Table/PayPalPaymentsTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use Cake\Event\EventList;
use Cake\Event\EventManager;
use Cake\ORM\Entity;
use Cake\TestSuite\TestCase;
use PayPal\Api\DetailedRefund;
use PayPal\Api\Payment;
use PayPal\Api\RelatedResources;
use PayPal\Api\Sale;
use PayPal\Api\Transaction;
use PayPal\Model\Entity\PayPalPayment;
use PayPal\Model\Table\PayPalPaymentsTable;
use PHPUnit\Framework\MockObject\MockObject;
Expand Down Expand Up @@ -63,6 +64,34 @@ public function testRefreshState()
$model->refreshState('1');
}

public function testRefund()
{
/** @var MockObject|PayPalPaymentsTable */
$model = $this->getMockForModel('PayPal.PayPalPayments', ['ApiGet', 'ApiRefundSale', 'savePayment']);

$payment = new Payment();
$transaction = new Transaction();
$sale = new Sale();
$sale->setId('123');
$relatedResources = new RelatedResources();
$relatedResources->setSale($sale);
$transaction->setRelatedResources($relatedResources);
$transactions = [$transaction];
$payment->setTransactions($transactions);
$model->expects($this->once())
->method('ApiGet')
->with('PayPalId')
->willReturn($payment);
$detailRefund = new DetailedRefund();
$model->expects($this->once())
->method('ApiRefundSale')
->with($sale)
->willReturn($detailRefund);

$actual = $model->refund(1);
$this->assertEquals($detailRefund, $actual);
}

public function testSavePayment()
{
/** @var PayPalPaymentsTable */
Expand Down

0 comments on commit 6be8643

Please sign in to comment.